⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vncconfig.cxx

📁 linux可以运行程序源码
💻 CXX
字号:
/* 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -