diff options
Diffstat (limited to 'unix/vncconfig')
-rw-r--r-- | unix/vncconfig/Makefile.in | 23 | ||||
-rw-r--r-- | unix/vncconfig/QueryConnectDialog.cxx | 88 | ||||
-rw-r--r-- | unix/vncconfig/QueryConnectDialog.h | 56 | ||||
-rw-r--r-- | unix/vncconfig/buildtime.c | 18 | ||||
-rw-r--r-- | unix/vncconfig/vncExt.c | 384 | ||||
-rw-r--r-- | unix/vncconfig/vncExt.h | 343 | ||||
-rw-r--r-- | unix/vncconfig/vncconfig.cxx | 438 | ||||
-rw-r--r-- | unix/vncconfig/vncconfig.man | 128 |
8 files changed, 1478 insertions, 0 deletions
diff --git a/unix/vncconfig/Makefile.in b/unix/vncconfig/Makefile.in new file mode 100644 index 00000000..4891fcd8 --- /dev/null +++ b/unix/vncconfig/Makefile.in @@ -0,0 +1,23 @@ + +SRCS = vncExt.c vncconfig.cxx QueryConnectDialog.cxx + +OBJS = vncExt.o vncconfig.o QueryConnectDialog.o + +program = vncconfig + +DEP_LIBS = ../tx/libtx.a ../rfb/librfb.a ../network/libnetwork.a \ + ../rdr/librdr.a + +EXTRA_LIBS = @X_PRE_LIBS@ @X_LIBS@ -lX11 -lXext @X_EXTRA_LIBS@ + +DIR_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/tx @X_CFLAGS@ # X_CFLAGS are really CPPFLAGS + +all:: $(program) + +$(program): $(OBJS) buildtime.o $(DEP_LIBS) + rm -f $(program) + $(CXXLD) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJS) buildtime.o $(DEP_LIBS) $(LIBS) $(EXTRA_LIBS) + +buildtime.o: $(OBJS) $(DEP_LIBS) + +# followed by boilerplate.mk diff --git a/unix/vncconfig/QueryConnectDialog.cxx b/unix/vncconfig/QueryConnectDialog.cxx new file mode 100644 index 00000000..c1540513 --- /dev/null +++ b/unix/vncconfig/QueryConnectDialog.cxx @@ -0,0 +1,88 @@ +/* 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 + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include <stdio.h> +#include <rdr/Exception.h> +#include "QueryConnectDialog.h" +#include "vncExt.h" + +QueryConnectDialog::QueryConnectDialog(Display* dpy, + const char* address_, + const char* user_, + int timeout_, + QueryResultCallback* cb) + : TXDialog(dpy, 300, 100, "VNC Server : Accept Connection?"), + addressLbl(dpy, "Host:",this), + address(dpy, address_, this), + userLbl(dpy, "User:", this), + user(dpy, user_, this), + timeoutLbl(dpy, "Seconds until automatic reject:", this), + timeout(dpy, "0000000000", this), + accept(dpy, "Accept", this, this, 60), + reject(dpy, "Reject", this, this, 60), + callback(cb), timeUntilReject(timeout_), timer(this) +{ + const int pad = 4; + int y=pad; + int lblWidth = __rfbmax(addressLbl.width(), userLbl.width()); + userLbl.move(pad+lblWidth-userLbl.width(), y); + user.move(pad+lblWidth, y); + addressLbl.move(pad+lblWidth-addressLbl.width(), y+=userLbl.height()); + address.move(pad+lblWidth, y); + timeoutLbl.move(pad, y+=addressLbl.height()); + timeout.move(pad+timeoutLbl.width(), y); + accept.move(pad, y+=addressLbl.height()); + int maxWidth = __rfbmax(user.width(), address.width()+pad+lblWidth); + maxWidth = __rfbmax(maxWidth, accept.width()*3); + maxWidth = __rfbmax(maxWidth, timeoutLbl.width()+timeout.width()+pad); + reject.move(maxWidth-reject.width(), y); + resize(maxWidth + pad, y+reject.height()+pad); + setBorderWidth(1); + refreshTimeout(); + timer.start(1000); +} + +void QueryConnectDialog::deleteWindow(TXWindow*) { + unmap(); + callback->queryRejected(); +} + +void QueryConnectDialog::buttonActivate(TXButton* b) { + unmap(); + if (b == &accept) + callback->queryApproved(); + else if (b == &reject) + callback->queryRejected(); +} + +bool QueryConnectDialog::handleTimeout(rfb::Timer* t) { + if (timeUntilReject-- == 0) { + unmap(); + callback->queryTimedOut(); + return false; + } else { + refreshTimeout(); + return true; + } +} + +void QueryConnectDialog::refreshTimeout() { + char buf[16]; + sprintf(buf, "%d", timeUntilReject); + timeout.setText(buf); +} diff --git a/unix/vncconfig/QueryConnectDialog.h b/unix/vncconfig/QueryConnectDialog.h new file mode 100644 index 00000000..f685dc34 --- /dev/null +++ b/unix/vncconfig/QueryConnectDialog.h @@ -0,0 +1,56 @@ +/* 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 + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef __QUERYCONNECTDIALOG_H__ +#define __QUERYCONNECTDIALOG_H__ + +#include <rfb/Timer.h> +#include "TXLabel.h" +#include "TXButton.h" +#include "TXDialog.h" + +class QueryResultCallback { + public: + virtual ~QueryResultCallback() {} + virtual void queryApproved() = 0; + virtual void queryRejected() = 0; + virtual void queryTimedOut() { queryRejected(); }; +}; + +class QueryConnectDialog : public TXDialog, public TXEventHandler, + public TXButtonCallback, + public rfb::Timer::Callback +{ + public: + QueryConnectDialog(Display* dpy, const char* address_, + const char* user_, int timeout_, + QueryResultCallback* cb); + void handleEvent(TXWindow*, XEvent* ) { } + void deleteWindow(TXWindow*); + void buttonActivate(TXButton* b); + bool handleTimeout(rfb::Timer* t); + private: + void refreshTimeout(); + TXLabel addressLbl, address, userLbl, user, timeoutLbl, timeout; + TXButton accept, reject; + QueryResultCallback* callback; + int timeUntilReject; + rfb::Timer timer; +}; + +#endif diff --git a/unix/vncconfig/buildtime.c b/unix/vncconfig/buildtime.c new file mode 100644 index 00000000..3f4c3690 --- /dev/null +++ b/unix/vncconfig/buildtime.c @@ -0,0 +1,18 @@ +/* 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 + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +char buildtime[] = __DATE__ " " __TIME__; diff --git a/unix/vncconfig/vncExt.c b/unix/vncconfig/vncExt.c new file mode 100644 index 00000000..ff5532bf --- /dev/null +++ b/unix/vncconfig/vncExt.c @@ -0,0 +1,384 @@ +/* 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 + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +#include <stdio.h> + +#define NEED_REPLIES +#include <X11/Xlib.h> +#include <X11/Xlibint.h> +#define _VNCEXT_PROTO_ +#include "vncExt.h" + +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; + +static Bool checkExtension(Display* dpy) +{ + if (!extensionInited) { + extensionInited = True; + codes = XInitExtension(dpy, VNCEXTNAME); + if (!codes) return False; + XESetWireToEvent(dpy, codes->first_event + VncExtClientCutTextNotify, + XVncExtClientCutTextNotifyWireToEvent); + XESetWireToEvent(dpy, codes->first_event + VncExtSelectionChangeNotify, + XVncExtSelectionChangeNotifyWireToEvent); + XESetWireToEvent(dpy, codes->first_event + VncExtQueryConnectNotify, + XVncExtQueryConnectNotifyWireToEvent); + } + return codes != 0; +} + +Bool XVncExtQueryExtension(Display* dpy, int* event_basep, int* error_basep) +{ + if (!checkExtension(dpy)) return False; + *event_basep = codes->first_event; + *error_basep = codes->first_error; + return True; +} + +Bool XVncExtSetParam(Display* dpy, const char* param) +{ + xVncExtSetParamReq* req; + xVncExtSetParamReply rep; + + int paramLen = strlen(param); + if (paramLen > 255) return False; + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtSetParam, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtSetParam; + req->length += (paramLen + 3) >> 2; + req->paramLen = paramLen; + Data(dpy, param, paramLen); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + return rep.success; +} + +Bool XVncExtGetParam(Display* dpy, const char* param, char** value, int* len) +{ + xVncExtGetParamReq* req; + xVncExtGetParamReply rep; + + int paramLen = strlen(param); + *value = 0; + *len = 0; + if (paramLen > 255) return False; + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtGetParam, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtGetParam; + req->length += (paramLen + 3) >> 2; + req->paramLen = paramLen; + Data(dpy, param, paramLen); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if (rep.success) { + *len = rep.valueLen; + *value = (char*) Xmalloc (*len+1); + _XReadPad(dpy, *value, *len); + (*value)[*len] = 0; + } + UnlockDisplay(dpy); + SyncHandle(); + return rep.success; +} + +char* XVncExtGetParamDesc(Display* dpy, const char* param) +{ + xVncExtGetParamDescReq* req; + xVncExtGetParamDescReply rep; + char* desc = 0; + + int paramLen = strlen(param); + if (paramLen > 255) return False; + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtGetParamDesc, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtGetParamDesc; + req->length += (paramLen + 3) >> 2; + req->paramLen = paramLen; + Data(dpy, param, paramLen); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + if (rep.success) { + desc = (char*)Xmalloc(rep.descLen+1); + _XReadPad(dpy, desc, rep.descLen); + desc[rep.descLen] = 0; + } + UnlockDisplay(dpy); + SyncHandle(); + return desc; +} + +char** XVncExtListParams(Display* dpy, int* nParams) +{ + xVncExtListParamsReq* req; + xVncExtListParamsReply rep; + char** list = 0; + char* ch; + int rlen, paramLen, i; + + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtListParams, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtListParams; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + if (rep.nParams) { + list = (char**)Xmalloc(rep.nParams * sizeof(char*)); + rlen = rep.length << 2; + ch = (char*)Xmalloc(rlen + 1); + if (!list || !ch) { + if (list) Xfree((char*)list); + if (ch) Xfree(ch); + _XEatData(dpy, rlen); + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + _XReadPad(dpy, ch, rlen); + paramLen = *ch++; + for (i = 0; i < rep.nParams; i++) { + list[i] = ch; + ch += paramLen; + paramLen = *ch; + *ch++ = 0; + } + } + *nParams = rep.nParams; + UnlockDisplay(dpy); + SyncHandle(); + return list; +} + +void XVncExtFreeParamList(char** list) +{ + if (list) { + Xfree(list[0]-1); + Xfree((char*)list); + } +} + +Bool XVncExtSetServerCutText(Display* dpy, const char* str, int len) +{ + xVncExtSetServerCutTextReq* req; + + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtSetServerCutText, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtSetServerCutText; + req->length += (len + 3) >> 2; + req->textLen = len; + Data(dpy, str, len); + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool XVncExtGetClientCutText(Display* dpy, char** str, int* len) +{ + xVncExtGetClientCutTextReq* req; + xVncExtGetClientCutTextReply rep; + + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtGetClientCutText, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtGetClientCutText; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + *len = rep.textLen; + *str = (char*) Xmalloc (*len+1); + _XReadPad(dpy, *str, *len); + (*str)[*len] = 0; + return True; +} + +Bool XVncExtSelectInput(Display* dpy, Window w, int mask) +{ + xVncExtSelectInputReq* req; + + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtSelectInput, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtSelectInput; + req->window = w; + req->mask = mask; + UnlockDisplay(dpy); + SyncHandle(); + return True; +} + +Bool XVncExtConnect(Display* dpy, char* hostAndPort) +{ + xVncExtConnectReq* req; + xVncExtConnectReply rep; + + int strLen = strlen(hostAndPort); + if (strLen > 255) return False; + if (!checkExtension(dpy)) return False; + + LockDisplay(dpy); + GetReq(VncExtConnect, req); + req->reqType = codes->major_opcode; + req->vncExtReqType = X_VncExtConnect; + req->length += (strLen + 3) >> 2; + req->strLen = strLen; + Data(dpy, hostAndPort, strLen); + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + 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) +{ + XVncExtClientCutTextEvent* ev = (XVncExtClientCutTextEvent*)e; + xVncExtClientCutTextNotifyEvent* wire = (xVncExtClientCutTextNotifyEvent*)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; + ev->time = wire->time; + return True; +} + +static Bool XVncExtSelectionChangeNotifyWireToEvent(Display* dpy, XEvent* e, + xEvent* w) +{ + XVncExtSelectionChangeEvent* ev = (XVncExtSelectionChangeEvent*)e; + xVncExtSelectionChangeNotifyEvent* wire + = (xVncExtSelectionChangeNotifyEvent*)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; + 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; +} diff --git a/unix/vncconfig/vncExt.h b/unix/vncconfig/vncExt.h new file mode 100644 index 00000000..f1502c41 --- /dev/null +++ b/unix/vncconfig/vncExt.h @@ -0,0 +1,343 @@ +/* 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 + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +#ifndef _VNCEXT_H_ +#define _VNCEXT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define X_VncExtSetParam 0 +#define X_VncExtGetParam 1 +#define X_VncExtGetParamDesc 2 +#define X_VncExtListParams 3 +#define X_VncExtSetServerCutText 4 +#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 3 +#define VncExtNumberErrors 0 + +#ifndef _VNCEXT_SERVER_ + +Bool XVncExtQueryExtension(Display* dpy, int* event_basep, int* error_basep); +Bool XVncExtSetParam(Display* dpy, const char* param); +Bool XVncExtGetParam(Display* dpy, const char* param, char** value, int* len); +char* XVncExtGetParamDesc(Display* dpy, const char* param); +char** XVncExtListParams(Display* dpy, int* nParams); +void XVncExtFreeParamList(char** list); +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; + unsigned long serial; + Bool send_event; + Display *display; + Window window; + Time time; +} XVncExtClientCutTextEvent; + +typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display *display; + Window window; + Atom selection; +} XVncExtSelectionChangeEvent; + +typedef struct { + int type; + unsigned long serial; + Bool send_event; + Display *display; + Window window; +} XVncExtQueryConnectEvent; + +#endif + +#ifdef _VNCEXT_PROTO_ + +#define VNCEXTNAME "VNC-EXTENSION" + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtSetParam */ + CARD16 length B16; + CARD8 paramLen; + CARD8 pad0; + CARD16 pad1 B16; +} xVncExtSetParamReq; +#define sz_xVncExtSetParamReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE success; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xVncExtSetParamReply; +#define sz_xVncExtSetParamReply 32 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtGetParam */ + CARD16 length B16; + CARD8 paramLen; + CARD8 pad0; + CARD16 pad1 B16; +} xVncExtGetParamReq; +#define sz_xVncExtGetParamReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE success; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 valueLen B16; + CARD16 pad0 B16; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xVncExtGetParamReply; +#define sz_xVncExtGetParamReply 32 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtGetParamDesc */ + CARD16 length B16; + CARD8 paramLen; + CARD8 pad0; + CARD16 pad1 B16; +} xVncExtGetParamDescReq; +#define sz_xVncExtGetParamDescReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE success; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 descLen B16; + CARD16 pad0 B16; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xVncExtGetParamDescReply; +#define sz_xVncExtGetParamDescReply 32 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtListParams */ + CARD16 length B16; +} xVncExtListParamsReq; +#define sz_xVncExtListParamsReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nParams B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVncExtListParamsReply; +#define sz_xVncExtListParamsReply 32 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtSetServerCutText */ + CARD16 length B16; + CARD32 textLen B32; +} xVncExtSetServerCutTextReq; +#define sz_xVncExtSetServerCutTextReq 8 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtGetClientCutText */ + CARD16 length B16; +} xVncExtGetClientCutTextReq; +#define sz_xVncExtGetClientCutTextReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 textLen B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xVncExtGetClientCutTextReply; +#define sz_xVncExtGetClientCutTextReply 32 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtSelectInput */ + CARD16 length B16; + CARD32 window B32; + CARD32 mask B32; +} xVncExtSelectInputReq; +#define sz_xVncExtSelectInputReq 12 + + +typedef struct { + CARD8 reqType; /* always VncExtReqCode */ + CARD8 vncExtReqType; /* always VncExtConnect */ + CARD16 length B16; + CARD8 strLen; + CARD8 pad0; + CARD16 pad1 B16; +} xVncExtConnectReq; +#define sz_xVncExtConnectReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE success; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad0 B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xVncExtConnectReply; +#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; + CARD16 sequenceNumber B16; + CARD32 window B32; + CARD32 time B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xVncExtClientCutTextNotifyEvent; +#define sz_xVncExtClientCutTextNotifyEvent 32 + +typedef struct { + BYTE type; /* always eventBase + VncExtSelectionChangeNotify */ + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 window B32; + CARD32 selection B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} 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 +} +#endif + +#endif diff --git a/unix/vncconfig/vncconfig.cxx b/unix/vncconfig/vncconfig.cxx new file mode 100644 index 00000000..c901d193 --- /dev/null +++ b/unix/vncconfig/vncconfig.cxx @@ -0,0 +1,438 @@ +/* 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 + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +// +// VNC server configuration utility +// + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> + +#include <signal.h> +#include <X11/X.h> +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <X11/Xutil.h> +#include <X11/keysym.h> +#include "vncExt.h" +#include <rdr/Exception.h> +#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; + +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" + +char* programName = 0; +Display* dpy; +int vncExtEventBase, vncExtErrorBase; + +static bool getBoolParam(Display* dpy, const char* param) { + char* data; + int len; + if (XVncExtGetParam(dpy, param, &data, &len)) { + if (strcmp(data,"1") == 0) return true; + } + return false; +} + +class VncConfigWindow : public TXWindow, public TXEventHandler, + public TXDeleteWindowCallback, + public TXCheckboxCallback, + public rfb::Timer::Callback, + public QueryResultCallback { +public: + VncConfigWindow(Display* dpy) + : 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), + 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)); + y += acceptClipboard.height(); + sendClipboard.move(xPad, y); + sendClipboard.checked(getBoolParam(dpy, SEND_CUT_TEXT)); + y += sendClipboard.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| + 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 + // primary and clipboard selections to the clientCutText. If we get a + // SelectionChangeNotify event from Xvnc, set the serverCutText to the value + // of the new selection. + + virtual void handleEvent(TXWindow* w, XEvent* ev) { + if (acceptClipboard.checked()) { + if (ev->type == vncExtEventBase + VncExtClientCutTextNotify) { + XVncExtClientCutTextEvent* cutEv = (XVncExtClientCutTextEvent*)ev; + 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 && 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); + } + } + } + + + // selectionRequest() is called when we are the selection owner and another X + // client has requested the selection. We simply put the server's cut text + // into the requested property. TXWindow will handle the rest. + bool selectionRequest(Window requestor, Atom selection, Atom property) + { + if (cutText) + XChangeProperty(dpy, requestor, property, XA_STRING, 8, + PropModeReplace, (unsigned char*)cutText, + cutTextLen); + return cutText; + } + + // selectionNotify() is called when we have requested the selection from the + // selection owner. + void selectionNotify(XSelectionEvent* ev, Atom type, int format, + int nitems, void* data) + { + if (ev->requestor != win() || ev->target != XA_STRING) + return; + + if (data && format == 8) { + 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); + } + } + + // TXDeleteWindowCallback method + virtual void deleteWindow(TXWindow* w) { + exit(1); + } + + // TXCheckboxCallback method + virtual void checkboxSelect(TXCheckbox* checkbox) { + if (checkbox == &acceptClipboard) { + XVncExtSetParam(dpy, (acceptClipboard.checked() + ? ACCEPT_CUT_TEXT "=1" : ACCEPT_CUT_TEXT "=0")); + } else if (checkbox == &sendClipboard) { + XVncExtSetParam(dpy, (sendClipboard.checked() + ? SEND_CUT_TEXT "=1" : SEND_CUT_TEXT "=0")); + 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* 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 [parameters]\n", + programName); + fprintf(stderr," %s [parameters] -connect <host>[:<port>]\n", + programName); + fprintf(stderr," %s [parameters] -disconnect\n", programName); + fprintf(stderr," %s [parameters] [-set] <Xvnc-param>=<value> ...\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); +} + +void removeArgs(int* argc, char** argv, int first, int n) +{ + if (first + n > *argc) return; + for (int i = first + n; i < *argc; i++) + argv[i-n] = argv[i]; + *argc -= n; +} + +int main(int argc, char** argv) +{ + programName = argv[0]; + rfb::initStdIOLoggers(); + rfb::LogWriter::setLogParams("*:stderr:30"); + + // Process vncconfig's own parameters first, then we process the + // other arguments when we have the X display. + int i; + for (i = 1; i < argc; i++) { + if (Configuration::setParam(argv[i])) + continue; + + if (argv[i][0] == '-' && i+1 < argc && + Configuration::setParam(&argv[i][1], argv[i+1])) { + i++; + continue; + } + break; + } + + CharArray displaynameStr(displayname.getData()); + if (!(dpy = XOpenDisplay(displaynameStr.buf))) { + fprintf(stderr,"%s: unable to open display \"%s\"\n", + programName, XDisplayName(displaynameStr.buf)); + exit(1); + } + + if (!XVncExtQueryExtension(dpy, &vncExtEventBase, &vncExtErrorBase)) { + fprintf(stderr,"No VNC extension on display %s\n", + XDisplayName(displaynameStr.buf)); + exit(1); + } + + if (i < argc) { + for (; i < argc; i++) { + if (strcmp(argv[i], "-connect") == 0) { + i++; + if (i >= argc) usage(); + if (!XVncExtConnect(dpy, argv[i])) { + fprintf(stderr,"connecting to %s failed\n",argv[i]); + } + } else if (strcmp(argv[i], "-disconnect") == 0) { + if (!XVncExtConnect(dpy, "")) { + fprintf(stderr,"disconnecting all clients failed\n"); + } + } else if (strcmp(argv[i], "-get") == 0) { + i++; + if (i >= argc) usage(); + char* data; + int len; + if (XVncExtGetParam(dpy, argv[i], &data, &len)) { + printf("%.*s\n",len,data); + } else { + fprintf(stderr,"getting param %s failed\n",argv[i]); + } + XFree(data); + } else if (strcmp(argv[i], "-desc") == 0) { + i++; + if (i >= argc) usage(); + char* desc = XVncExtGetParamDesc(dpy, argv[i]); + if (desc) { + printf("%s\n",desc); + } else { + fprintf(stderr,"getting description for param %s failed\n",argv[i]); + } + XFree(desc); + } else if (strcmp(argv[i], "-list") == 0) { + int nParams; + char** list = XVncExtListParams(dpy, &nParams); + for (int i = 0; i < nParams; i++) { + printf("%s\n",list[i]); + } + XVncExtFreeParamList(list); + } else if (strcmp(argv[i], "-set") == 0) { + i++; + if (i >= argc) usage(); + if (!XVncExtSetParam(dpy, argv[i])) { + fprintf(stderr,"setting param %s failed\n",argv[i]); + } + } else if (XVncExtSetParam(dpy, argv[i])) { + fprintf(stderr,"set parameter %s\n",argv[i]); + } else { + usage(); + } + } + + return 0; + } + + try { + TXWindow::init(dpy,"Vncconfig"); + + VncConfigWindow w(dpy); + 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, tvp); + if (n < 0) throw rdr::SystemException("select",errno); + } + + XCloseDisplay(dpy); + + } catch (rdr::Exception &e) { + vlog.error(e.str()); + } + + return 0; +} diff --git a/unix/vncconfig/vncconfig.man b/unix/vncconfig/vncconfig.man new file mode 100644 index 00000000..e24753da --- /dev/null +++ b/unix/vncconfig/vncconfig.man @@ -0,0 +1,128 @@ +.TH vncconfig 1 "17 Apr 2006" "TightVNC" "Virtual Network Computing" +.SH NAME +vncconfig \- configure and control a VNC server +.SH SYNOPSIS +.B vncconfig +.RI [ parameters ] +.br +.B vncconfig +.RI [ parameters ] +.B \-connect +.IR host [: port ] +.br +.B vncconfig +.RI [ parameters ] +.B \-disconnect +.br +.B vncconfig +.RI [ parameters ] +.RB [ -set ] +.IR Xvnc-param = value " ..." +.br +.B vncconfig +.RI [ parameters ] +.B \-list +.br +.B vncconfig +.RI [ parameters ] +\fB\-get\fP \fIXvnc-param\fP +.br +.B vncconfig +.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 +server with the VNC extension. Note that it cannot be used to control VNC +servers prior to version 4. + +When run with no options, it runs as a kind of "helper" application for Xvnc. +Its main purpose when run in this mode is to support clipboard transfer to and +from the VNC viewer(s). Note that without a running instance of +\fBvncconfig\fP there will be no clipboard support. It puts up a window with +some checkboxes which can be used to disable clipboard transfers if required +(in the future there may be more functions available from this window). The +\fB-nowin\fP flag can be used if you always want clipboard support but don't +wish to clutter the desktop with this window - alternatively the \fB-iconic\fP +option can be used to make it iconified by default. + +When run in any other mode, \fBvncconfig\fP is a one-shot program used to +configure or control Xvnc as appropriate. It can be used to tell Xvnc to +connect or disconnect from listening viewers, and to set and retrieve Xvnc's +parameters. + +Note that the DISPLAY environment variable or the \fB\-display\fP option +must be set as appropriate to control Xvnc. If you run it on an ordinary X +server (or on a version 3 Xvnc) you will get an error message saying that there +is no VNC extension. + +.SH OPTIONS +.TP +.B \-connect \fIhost\fP[:\fIport\fP] +Tells an Xvnc server to make a "reverse" connection to a listening VNC viewer +(normally connections are made the other way round - the viewer connects to the +server). \fIhost\fP is the host where the listening viewer is running. If it's +not listening on the default port of 5500, you can specify \fIhost:port\fP +instead. + +.TP +.B \-disconnect +This causes Xvnc to disconnect from all viewers so that the VNC desktop is not +displayed anywhere. + +.TP +[\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. + +.TP +.B \-list +Lists all the parameters supported by Xvnc. + +.TP +.B \-get \fIXvnc-param\fP +Prints the current value of the given Xvnc parameter. + +.TP +.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), +.BR vncserver (1), +.BR Xvnc (1) +.br +http://www.tightvnc.com + +.SH AUTHOR +Tristan Richardson, RealVNC Ltd. + +VNC was originally developed by the RealVNC team while at Olivetti +Research Ltd / AT&T Laboratories Cambridge. TightVNC additions was +implemented by Constantin Kaplinsky. Many other people participated in +development, testing and support. |