]> source.dussan.org Git - tigervnc.git/commitdiff
vncconfig_unix directory merged with VNC 4.1.1 code.
authorConstantin Kaplinsky <const@tightvnc.com>
Mon, 17 Apr 2006 05:13:10 +0000 (05:13 +0000)
committerConstantin Kaplinsky <const@tightvnc.com>
Mon, 17 Apr 2006 05:13:10 +0000 (05:13 +0000)
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@527 3789f03b-4d11-0410-bbf8-ca57d06f2519

vncconfig_unix/Makefile.in
vncconfig_unix/buildtime.c
vncconfig_unix/vncExt.c
vncconfig_unix/vncExt.h
vncconfig_unix/vncconfig.cxx
vncconfig_unix/vncconfig.man

index 58277c3a0748800678155ebcdd09ea80bee444b8..4891fcd8195c7ff7230f7d98d23850ac09736e09 100644 (file)
@@ -1,7 +1,7 @@
 
-SRCS = vncExt.c vncconfig.cxx
+SRCS = vncExt.c vncconfig.cxx QueryConnectDialog.cxx
 
-OBJS = vncExt.o vncconfig.o
+OBJS = vncExt.o vncconfig.o QueryConnectDialog.o
 
 program = vncconfig
 
index a96031ccc162103aef317af2c60f40a1a10a0c82..3f4c36902862067dd6b173c4b0e63367b139e424 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
index ac1dab37ad746756d1e7d70b600d3583b5b69aea..ff5532bf20fe80b248f84146b42dde1b65e9f295 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -18,6 +18,7 @@
 #include <stdio.h>
 
 #define NEED_REPLIES
+#include <X11/Xlib.h>
 #include <X11/Xlibint.h>
 #define _VNCEXT_PROTO_
 #include "vncExt.h"
@@ -26,6 +27,8 @@ static Bool XVncExtClientCutTextNotifyWireToEvent(Display* dpy, XEvent* e,
                                                   xEvent* w);
 static Bool XVncExtSelectionChangeNotifyWireToEvent(Display* dpy, XEvent* e,
                                                     xEvent* w);
+static Bool XVncExtQueryConnectNotifyWireToEvent(Display* dpy, XEvent* e,
+                                                 xEvent* w);
 
 static Bool extensionInited = False;
 static XExtCodes* codes = 0;
@@ -40,6 +43,8 @@ static Bool checkExtension(Display* dpy)
                      XVncExtClientCutTextNotifyWireToEvent);
     XESetWireToEvent(dpy, codes->first_event + VncExtSelectionChangeNotify,
                      XVncExtSelectionChangeNotifyWireToEvent);
+    XESetWireToEvent(dpy, codes->first_event + VncExtQueryConnectNotify,
+                     XVncExtQueryConnectNotifyWireToEvent);
   }
   return codes != 0;
 }
@@ -286,6 +291,55 @@ Bool XVncExtConnect(Display* dpy, char* hostAndPort)
   return rep.success;
 }
 
+Bool XVncExtGetQueryConnect(Display* dpy, char** addr, char** user,
+                            int* timeout, void** opaqueId)
+{
+  xVncExtGetQueryConnectReq* req;
+  xVncExtGetQueryConnectReply rep;
+
+  if (!checkExtension(dpy)) return False;
+
+  LockDisplay(dpy);
+  GetReq(VncExtGetQueryConnect, req);
+  req->reqType = codes->major_opcode;
+  req->vncExtReqType = X_VncExtGetQueryConnect;
+  if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+    UnlockDisplay(dpy);
+    SyncHandle();
+    return False;
+  }
+  UnlockDisplay(dpy);
+  SyncHandle();
+
+  *addr = Xmalloc(rep.addrLen+1);
+  _XReadPad(dpy, *addr, rep.addrLen);
+  (*addr)[rep.addrLen] = 0;
+  *user = Xmalloc(rep.userLen+1);
+  _XReadPad(dpy, *user, rep.userLen);
+  (*user)[rep.userLen] = 0;
+  *timeout = rep.timeout;
+  *opaqueId = (void*)rep.opaqueId;
+  return True;
+}
+
+Bool XVncExtApproveConnect(Display* dpy, void* opaqueId, int approve)
+{
+  xVncExtApproveConnectReq* req;
+
+  if (!checkExtension(dpy)) return False;
+
+  LockDisplay(dpy);
+  GetReq(VncExtApproveConnect, req);
+  req->reqType = codes->major_opcode;
+  req->vncExtReqType = X_VncExtApproveConnect;
+  req->approve = approve;
+  req->opaqueId = (CARD32)opaqueId;
+  UnlockDisplay(dpy);
+  SyncHandle();
+  return True;
+}
+
+
 static Bool XVncExtClientCutTextNotifyWireToEvent(Display* dpy, XEvent* e,
                                                   xEvent* w)
 {
@@ -314,3 +368,17 @@ static Bool XVncExtSelectionChangeNotifyWireToEvent(Display* dpy, XEvent* e,
   ev->selection = wire->selection;
   return True;
 }
+
+static Bool XVncExtQueryConnectNotifyWireToEvent(Display* dpy, XEvent* e,
+                                                    xEvent* w)
+{
+  XVncExtQueryConnectEvent* ev = (XVncExtQueryConnectEvent*)e;
+  xVncExtQueryConnectNotifyEvent* wire
+    = (xVncExtQueryConnectNotifyEvent*)w;
+  ev->type = wire->type & 0x7f;
+  ev->serial = _XSetLastRequestRead(dpy,(xGenericReply*)wire);
+  ev->send_event = (wire->type & 0x80) != 0;
+  ev->display = dpy;
+  ev->window = wire->window;
+  return True;
+}
index de69f4ed312c7b667080427222bae2911c9bc88f..f1502c41651975073f41e4fbe1d1ef53f77f6e14 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2003 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -30,13 +30,17 @@ extern "C" {
 #define X_VncExtGetClientCutText 5
 #define X_VncExtSelectInput 6
 #define X_VncExtConnect 7
+#define X_VncExtGetQueryConnect 8
+#define X_VncExtApproveConnect 9
 
 #define VncExtClientCutTextNotify 0
 #define VncExtSelectionChangeNotify 1
+#define VncExtQueryConnectNotify 2
 #define VncExtClientCutTextMask (1 << VncExtClientCutTextNotify)
 #define VncExtSelectionChangeMask (1 << VncExtSelectionChangeNotify)
+#define VncExtQueryConnectMask (1 << VncExtQueryConnectNotify)
 
-#define VncExtNumberEvents 2
+#define VncExtNumberEvents 3
 #define VncExtNumberErrors 0
 
 #ifndef _VNCEXT_SERVER_
@@ -51,6 +55,10 @@ Bool XVncExtSetServerCutText(Display* dpy, const char* str, int len);
 Bool XVncExtGetClientCutText(Display* dpy, char** str, int* len);
 Bool XVncExtSelectInput(Display* dpy, Window w, int mask);
 Bool XVncExtConnect(Display* dpy, char* hostAndPort);
+Bool XVncExtGetQueryConnect(Display* dpy, char** addr,
+                            char** user, int* timeout, void** opaqueId);
+Bool XVncExtApproveConnect(Display* dpy, void* opaqueId, int approve);
+
 
 typedef struct {
   int type;
@@ -70,6 +78,14 @@ typedef struct {
   Atom selection;
 } XVncExtSelectionChangeEvent;
 
+typedef struct {
+  int type;
+  unsigned long serial;
+  Bool send_event;
+  Display *display;
+  Window window;
+} XVncExtQueryConnectEvent;
+
 #endif
 
 #ifdef _VNCEXT_PROTO_
@@ -242,6 +258,40 @@ typedef struct {
 #define sz_xVncExtConnectReply 32
 
 
+typedef struct {
+  CARD8 reqType;       /* always VncExtReqCode */
+  CARD8 vncExtReqType; /* always VncExtGetQueryConnect */
+  CARD16 length B16;
+} xVncExtGetQueryConnectReq;
+#define sz_xVncExtGetQueryConnectReq 4
+
+typedef struct {
+ BYTE type; /* X_Reply */
+ BYTE pad0;
+ CARD16 sequenceNumber B16;
+ CARD32 length B32;
+ CARD32 addrLen B32;
+ CARD32 userLen B32;
+ CARD32 timeout B32;
+ CARD32 opaqueId B32;
+ CARD32 pad4 B32;
+ CARD32 pad5 B32;
+} xVncExtGetQueryConnectReply;
+#define sz_xVncExtGetQueryConnectReply 32
+
+typedef struct {
+  CARD8 reqType;       /* always VncExtReqCode */
+  CARD8 vncExtReqType; /* always VncExtApproveConnect */
+  CARD16 length B16;
+  CARD8 approve;
+  CARD8 pad0;
+  CARD16 pad1;
+  CARD32 opaqueId B32;
+} xVncExtApproveConnectReq;
+#define sz_xVncExtApproveConnectReq 12
+
+
+
 typedef struct {
   BYTE type;    /* always eventBase + VncExtClientCutTextNotify */
   BYTE pad0;
@@ -270,6 +320,20 @@ typedef struct {
 } xVncExtSelectionChangeNotifyEvent;
 #define sz_xVncExtSelectionChangeNotifyEvent 32
 
+typedef struct {
+  BYTE type;    /* always eventBase + VncExtQueryConnectNotify */
+  BYTE pad0;
+  CARD16 sequenceNumber B16;
+  CARD32 window B32;
+  CARD32 pad6 B32;
+  CARD32 pad1 B32;
+  CARD32 pad2 B32;
+  CARD32 pad3 B32;
+  CARD32 pad4 B32;
+  CARD32 pad5 B32;
+} xVncExtQueryConnectNotifyEvent;
+#define sz_xVncExtQueryConnectNotifyEvent 32
+
 #endif
 
 #ifdef __cplusplus
index e707ffb9b9bda9f06486268a1017a5e9f00b1b73..c901d1937c74d496907336d8800aa61e536b6d32 100644 (file)
@@ -1,5 +1,5 @@
-/* Copyright (C) 2002-2004 RealVNC Ltd.  All Rights Reserved.
- *    
+/* Copyright (C) 2002-2005 RealVNC Ltd.  All Rights Reserved.
+ * 
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
 #include <rfb/Configuration.h>
 #include <rfb/Logger_stdio.h>
 #include <rfb/LogWriter.h>
+#include <rfb/Timer.h>
 #include "TXWindow.h"
 #include "TXCheckbox.h"
+#include "TXLabel.h"
+#include "QueryConnectDialog.h"
 
 using namespace rfb;
 
@@ -48,6 +51,16 @@ LogWriter vlog("vncconfig");
 StringParameter displayname("display", "The X display", "");
 BoolParameter noWindow("nowin", "Don't display a window", 0);
 BoolParameter iconic("iconic", "Start with window iconified", 0);
+BoolParameter sendPrimary("SendPrimary", "Send the PRIMARY as well as the "
+                          "CLIPBOARD selection", true);
+IntParameter pollTime("poll",
+                      "How often to poll for clipboard changes in ms", 0);
+
+inline const char* selectionName(Atom sel) {
+  if (sel == xaCLIPBOARD) return "CLIPBOARD";
+  if (sel == XA_PRIMARY) return "PRIMARY";
+  return "unknown";
+}
 
 #define ACCEPT_CUT_TEXT "AcceptCutText"
 #define SEND_CUT_TEXT "SendCutText"
@@ -67,14 +80,20 @@ static bool getBoolParam(Display* dpy, const char* param) {
 
 class VncConfigWindow : public TXWindow, public TXEventHandler,
                         public TXDeleteWindowCallback,
-                        public TXCheckboxCallback {
+                        public TXCheckboxCallback,
+                        public rfb::Timer::Callback,
+                        public QueryResultCallback {
 public:
   VncConfigWindow(Display* dpy)
-    : TXWindow(dpy, 300, 100), clientCutText(0), clientCutTextLen(0),
+    : TXWindow(dpy, 300, 100), cutText(0), cutTextLen(0),
       acceptClipboard(dpy, "Accept clipboard from viewers", this, false, this),
       sendClipboard(dpy, "Send clipboard to viewers", this, false, this),
-      sendPrimary(dpy, "Send primary selection to viewers", this, false, this)
+      sendPrimaryCB(dpy, "Send primary selection to viewers", this,false,this),
+      pollTimer(this),
+      queryConnectDialog(0)
   {
+    selection[0] = selection[1] = 0;
+    selectionLen[0] = selectionLen[1] = 0;
     int y = yPad;
     acceptClipboard.move(xPad, y);
     acceptClipboard.checked(getBoolParam(dpy, ACCEPT_CUT_TEXT));
@@ -82,14 +101,22 @@ public:
     sendClipboard.move(xPad, y);
     sendClipboard.checked(getBoolParam(dpy, SEND_CUT_TEXT));
     y += sendClipboard.height();
-    sendPrimary.move(xPad, y);
-    sendPrimary.checked(true);
-    sendPrimary.disabled(!sendClipboard.checked());
-    y += sendPrimary.height();
+    sendPrimaryCB.move(xPad, y);
+    sendPrimaryCB.checked(sendPrimary);
+    sendPrimaryCB.disabled(!sendClipboard.checked());
+    y += sendPrimaryCB.height();
     setEventHandler(this);
     toplevel("VNC config", this, 0, 0, 0, iconic);
     XVncExtSelectInput(dpy, win(),
-                       VncExtClientCutTextMask|VncExtSelectionChangeMask);
+                       VncExtClientCutTextMask|
+                       VncExtSelectionChangeMask|
+                       VncExtQueryConnectMask);
+    XConvertSelection(dpy, XA_PRIMARY, XA_STRING,
+                      XA_PRIMARY, win(), CurrentTime);
+    XConvertSelection(dpy, xaCLIPBOARD, XA_STRING,
+                      xaCLIPBOARD, win(), CurrentTime);
+    if (pollTime != 0)
+      pollTimer.start(pollTime);
   }
 
   // handleEvent(). If we get a ClientCutTextNotify event from Xvnc, set the
@@ -101,28 +128,55 @@ public:
     if (acceptClipboard.checked()) {
       if (ev->type == vncExtEventBase + VncExtClientCutTextNotify) {
         XVncExtClientCutTextEvent* cutEv = (XVncExtClientCutTextEvent*)ev;
-        if (clientCutText)
-          XFree(clientCutText);
-        clientCutText = 0;
-        if (XVncExtGetClientCutText(dpy, &clientCutText, &clientCutTextLen)) {
-          vlog.debug("Got client cut text");
-          XStoreBytes(dpy, clientCutText, clientCutTextLen);
+        if (cutText)
+          XFree(cutText);
+        cutText = 0;
+        if (XVncExtGetClientCutText(dpy, &cutText, &cutTextLen)) {
+          vlog.debug("Got client cut text: '%.*s%s'",
+                     cutTextLen<9?cutTextLen:8, cutText,
+                     cutTextLen<9?"":"...");
+          XStoreBytes(dpy, cutText, cutTextLen);
           ownSelection(XA_PRIMARY, cutEv->time);
           ownSelection(xaCLIPBOARD, cutEv->time);
+          delete [] selection[0];
+          delete [] selection[1];
+          selection[0] = selection[1] = 0;
+          selectionLen[0] = selectionLen[1] = 0;
         }
       }
     }
     if (sendClipboard.checked()) {
       if (ev->type == vncExtEventBase + VncExtSelectionChangeNotify) {
+        vlog.debug("selection change event");
         XVncExtSelectionChangeEvent* selEv = (XVncExtSelectionChangeEvent*)ev;
         if (selEv->selection == xaCLIPBOARD ||
-            (selEv->selection == XA_PRIMARY && sendPrimary.checked())) {
+            (selEv->selection == XA_PRIMARY && sendPrimaryCB.checked())) {
           if (!selectionOwner(selEv->selection))
             XConvertSelection(dpy, selEv->selection, XA_STRING,
                               selEv->selection, win(), CurrentTime);
         }
       }
     }
+    if (ev->type == vncExtEventBase + VncExtQueryConnectNotify) {
+       vlog.debug("query connection event");
+       if (queryConnectDialog)
+         delete queryConnectDialog;
+       queryConnectDialog = 0;
+       char* qcAddress;
+       char* qcUser;
+       int qcTimeout;
+       if (XVncExtGetQueryConnect(dpy, &qcAddress, &qcUser,
+                                  &qcTimeout, &queryConnectId)) {
+         if (qcTimeout)
+           queryConnectDialog = new QueryConnectDialog(dpy, qcAddress,
+                                                       qcUser, qcTimeout,
+                                                       this);
+         if (queryConnectDialog)
+           queryConnectDialog->map();
+         XFree(qcAddress);
+         XFree(qcUser);
+       }
+    }
   }
   
 
@@ -131,11 +185,11 @@ public:
   // into the requested property.  TXWindow will handle the rest.
   bool selectionRequest(Window requestor, Atom selection, Atom property)
   {
-    if (clientCutText)
+    if (cutText)
       XChangeProperty(dpy, requestor, property, XA_STRING, 8,
-                      PropModeReplace, (unsigned char*)clientCutText,
-                      clientCutTextLen);
-    return clientCutText;
+                      PropModeReplace, (unsigned char*)cutText,
+                      cutTextLen);
+    return cutText;
   }
 
   // selectionNotify() is called when we have requested the selection from the
@@ -147,8 +201,26 @@ public:
       return;
 
     if (data && format == 8) {
-      vlog.debug("setting selection as server cut text");
-      XVncExtSetServerCutText(dpy, (char*)data, nitems);
+      int i = (ev->selection == XA_PRIMARY ? 0 : 1);
+      if (selectionLen[i] == nitems && memcmp(selection[i], data, nitems) == 0)
+        return;
+      delete [] selection[i];
+      selection[i] = new char[nitems];
+      memcpy(selection[i], data, nitems);
+      selectionLen[i] = nitems;
+      if (cutTextLen == nitems && memcmp(cutText, data, nitems) == 0) {
+        vlog.debug("ignoring duplicate cut text");
+        return;
+      }
+      if (cutText)
+        XFree(cutText);
+      cutText = (char*)malloc(nitems); // assuming XFree() same as free()
+      memcpy(cutText, data, nitems);
+      cutTextLen = nitems;
+      vlog.debug("sending %s selection as server cut text: '%.*s%s'",
+                 selectionName(ev->selection),cutTextLen<9?cutTextLen:8,
+                 cutText, cutTextLen<9?"":"...");
+      XVncExtSetServerCutText(dpy, cutText, cutTextLen);
     }
   }
 
@@ -165,28 +237,61 @@ public:
     } else if (checkbox == &sendClipboard) {
       XVncExtSetParam(dpy, (sendClipboard.checked()
                             ? SEND_CUT_TEXT "=1" : SEND_CUT_TEXT "=0"));
-      sendPrimary.disabled(!sendClipboard.checked());
+      sendPrimaryCB.disabled(!sendClipboard.checked());
     }
   }
 
+  // rfb::Timer::Callback interface
+  virtual bool handleTimeout(rfb::Timer* timer) {
+    if (sendPrimaryCB.checked() && !selectionOwner(XA_PRIMARY))
+      XConvertSelection(dpy, XA_PRIMARY, XA_STRING,
+                        XA_PRIMARY, win(), CurrentTime);
+    if (!selectionOwner(xaCLIPBOARD))
+      XConvertSelection(dpy, xaCLIPBOARD, XA_STRING,
+                        xaCLIPBOARD, win(), CurrentTime);
+    return true;
+  }
+
+  // QueryResultCallback interface
+  virtual void queryApproved() {
+    XVncExtApproveConnect(dpy, queryConnectId, 1);
+  }
+  virtual void queryRejected() {
+    XVncExtApproveConnect(dpy, queryConnectId, 0);
+  }
+
 private:
-  char* clientCutText;
-  int clientCutTextLen;
-  TXCheckbox acceptClipboard, sendClipboard, sendPrimary;
+  char* cutText;
+  int cutTextLen;
+  char* selection[2];
+  int selectionLen[2];
+  TXCheckbox acceptClipboard, sendClipboard, sendPrimaryCB;
+  rfb::Timer pollTimer;
+
+  QueryConnectDialog* queryConnectDialog;
+  void* queryConnectId;
 };
 
 static void usage()
 {
-  fprintf(stderr,"usage: %s [-display <display>] [-nowin] [-iconic]\n",
+  fprintf(stderr,"usage: %s [parameters]\n",
           programName);
-  fprintf(stderr,"       %s [-display <display>] -connect <host>[:<port>]\n",
+  fprintf(stderr,"       %s [parameters] -connect <host>[:<port>]\n",
           programName);
-  fprintf(stderr,"       %s [-display <display>] -disconnect\n", programName);
-  fprintf(stderr,"       %s [-display <display>] [-set] <param>=<value> ...\n",
+  fprintf(stderr,"       %s [parameters] -disconnect\n", programName);
+  fprintf(stderr,"       %s [parameters] [-set] <Xvnc-param>=<value> ...\n",
           programName);
-  fprintf(stderr,"       %s [-display <display>] -list\n", programName);
-  fprintf(stderr,"       %s [-display <display>] -get <param>\n", programName);
-  fprintf(stderr,"       %s [-display <display>] -desc <param>\n",programName);
+  fprintf(stderr,"       %s [parameters] -list\n", programName);
+  fprintf(stderr,"       %s [parameters] -get <param>\n", programName);
+  fprintf(stderr,"       %s [parameters] -desc <param>\n",programName);
+  fprintf(stderr,"\n"
+          "Parameters can be turned on with -<param> or off with -<param>=0\n"
+          "Parameters which take a value can be specified as "
+          "-<param> <value>\n"
+          "Other valid forms are <param>=<value> -<param>=<value> "
+          "--<param>=<value>\n"
+          "Parameter names are case-insensitive.  The parameters are:\n\n");
+  Configuration::listParams(79, 14);
   exit(1);
 }
 
@@ -295,11 +400,31 @@ int main(int argc, char** argv)
     if (!noWindow) w.map();
 
     while (true) {
+      struct timeval tv;
+      struct timeval* tvp = 0;
+
+      // Process any incoming X events
       TXWindow::handleXEvents(dpy);
+      
+      // Process expired timers and get the time until the next one
+      int timeoutMs = Timer::checkTimeouts();
+      if (timeoutMs) {
+        tv.tv_sec = timeoutMs / 1000;
+        tv.tv_usec = (timeoutMs % 1000) * 1000;
+        tvp = &tv;
+      }
+      
+      // If there are X requests pending then poll, don't wait!
+      if (XPending(dpy)) {
+        tv.tv_usec = tv.tv_sec = 0;
+        tvp = &tv;
+      }
+      
+      // Wait for X events, VNC traffic, or the next timer expiry
       fd_set rfds;
       FD_ZERO(&rfds);
       FD_SET(ConnectionNumber(dpy), &rfds);
-      int n = select(FD_SETSIZE, &rfds, 0, 0, 0);
+      int n = select(FD_SETSIZE, &rfds, 0, 0, tvp);
       if (n < 0) throw rdr::SystemException("select",errno);
     }
 
index 33f7d4910745d1b091ab747cb083e179b1a58290..e24753da301df23af0eb7b5f2f806b9f94f44c83 100644 (file)
@@ -1,34 +1,35 @@
-.TH vncconfig 1 "30 December 2004" "TightVNC" "Virtual Network Computing"
+.TH vncconfig 1 "17 Apr 2006" "TightVNC" "Virtual Network Computing"
 .SH NAME
 vncconfig \- configure and control a VNC server
 .SH SYNOPSIS
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP] [\fB\-nowin\fP] [\fB\-iconic\fP]
+.RI [ parameters ] 
 .br
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP]
+.RI [ parameters ] 
 .B \-connect
 .IR host [: port ]
 .br
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP]
+.RI [ parameters ] 
 .B \-disconnect
 .br
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP]
-.IR param = value " ..."
+.RI [ parameters ] 
+.RB [ -set ] 
+.IR Xvnc-param = value " ..."
 .br
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP]
+.RI [ parameters ] 
 .B \-list
 .br
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP]
-\fB\-get\fP \fIparam\fP
+.RI [ parameters ] 
+\fB\-get\fP \fIXvnc-param\fP
 .br
 .B vncconfig
-[\fB\-display\fP \fIXdisplay\fP]
-\fB\-desc\fP \fIparam\fP
+.RI [ parameters ] 
+\fB\-desc\fP \fIXvnc-param\fP
 .SH DESCRIPTION
 .B vncconfig
 is used to configure and control a running instance of Xvnc, or any other X
@@ -56,18 +57,6 @@ server (or on a version 3 Xvnc) you will get an error message saying that there
 is no VNC extension.
 
 .SH OPTIONS
-.TP
-.B \-display \fIXdisplay\fP
-Specifies the Xvnc server to control.
-
-.TP
-.B \-nowin
-When run as a "helper" app, don't put up a window.
-
-.TP
-.B \-iconic
-When run as a "helper" app, make the window iconified at startup.
-
 .TP
 .B \-connect \fIhost\fP[:\fIport\fP]
 Tells an Xvnc server to make a "reverse" connection to a listening VNC viewer
@@ -82,7 +71,7 @@ This causes Xvnc to disconnect from all viewers so that the VNC desktop is not
 displayed anywhere.
 
 .TP
-.IR param = value
+[\fB-set\fP] \fIXvnc-param\fP=\fIvalue\fP
 Sets an Xvnc parameter to the given value.  Note that some of Xvnc's parameters
 are read only once at startup so that changing them in this way may not have
 any effect.
@@ -92,13 +81,36 @@ any effect.
 Lists all the parameters supported by Xvnc.
 
 .TP
-.B \-get \fIparam\fP
+.B \-get \fIXvnc-param\fP
 Prints the current value of the given Xvnc parameter.
 
 .TP
-.B \-desc \fIparam\fP
+.B \-desc \fIXvnc-param\fP
 Prints a short description of the given Xvnc parameter.
 
+.SH PARAMETERS
+.B vncconfig
+also has parameters of its own which can be set on the command line.  These
+should not be confused with Xvnc's parameters which are manipulated with the
+\fB-set\fP, \fB-get\fP, \fB-list\fP and \fB-desc\fP options.
+
+Parameters can be turned on with -\fIparam\fP or off with -\fIparam\fP=0.
+Parameters which take a value can be specified as -\fIparam\fP \fIvalue\fP.
+Other valid forms are \fIparam\fP\fB=\fP\fIvalue\fP -\fIparam\fP=\fIvalue\fP
+--\fIparam\fP=\fIvalue\fP.  Parameter names are case-insensitive.
+
+.TP
+.B \-display \fIXdisplay\fP
+Specifies the Xvnc server to control.
+
+.TP
+.B \-nowin
+When run as a "helper" app, don't put up a window.
+
+.TP
+.B \-iconic
+When run as a "helper" app, make the window iconified at startup.
+
 .SH SEE ALSO
 .BR vncpasswd (1),
 .BR vncviewer (1),