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

📄 x0vncserver.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. */#include <strings.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>#include <rfb/Logger_stdio.h>#include <rfb/LogWriter.h>#include <rfb/VNCServerST.h>#include <rfb/Configuration.h>#include <rfb/SSecurityFactoryStandard.h>#include <rfb/Timer.h>#include <network/TcpSocket.h>#include <tx/TXWindow.h>#include "QueryConnectDialog.h"#include "Image.h"#include <signal.h>#include <X11/X.h>#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/extensions/XTest.h>//#include <rfb/Encoder.h>using namespace rfb;using namespace rdr;using namespace network;LogWriter vlog("main");StringParameter displayname("display", "The X display", "");IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol",5900);IntParameter queryConnectTimeout("QueryConnectTimeout",                                 "Number of seconds to show the Accept Connection dialog before "                                 "rejecting the connection",                                 10);static void CleanupSignalHandler(int sig){  // CleanupSignalHandler allows C++ object cleanup to happen because it calls  // exit() rather than the default which is to abort.  fprintf(stderr,"CleanupSignalHandler called\n");  exit(1);}class QueryConnHandler : public VNCServerST::QueryConnectionHandler,                         public QueryResultCallback {public:  QueryConnHandler(Display* dpy, VNCServerST* vs)    : display(dpy), server(vs), queryConnectDialog(0), queryConnectSock(0) {}  ~QueryConnHandler() { delete queryConnectDialog; }  // -=- VNCServerST::QueryConnectionHandler interface  virtual VNCServerST::queryResult queryConnection(network::Socket* sock,                                                   const char* userName,                                                   char** reason) {    if (queryConnectSock) {      *reason = strDup("Another connection is currently being queried.");      return VNCServerST::REJECT;    }    if (!userName) userName = "(anonymous)";    queryConnectSock = sock;    CharArray address(sock->getPeerAddress());    delete queryConnectDialog;    queryConnectDialog = new QueryConnectDialog(display, address.buf,                                                userName, queryConnectTimeout,                                                this);    queryConnectDialog->map();    return VNCServerST::PENDING;  }  // -=- QueryResultCallback interface  virtual void queryApproved() {    server->approveConnection(queryConnectSock, true, 0);    queryConnectSock = 0;  }  virtual void queryRejected() {    server->approveConnection(queryConnectSock, false,                              "Connection rejected by local user");    queryConnectSock = 0;  }private:  Display* display;  VNCServerST* server;  QueryConnectDialog* queryConnectDialog;  network::Socket* queryConnectSock;};class XDesktop : public SDesktop, public ColourMap,                 public Timer::Callback{public:  XDesktop(Display* dpy_)    : dpy(dpy_), pb(0), server(0), image(0), oldButtonMask(0),      haveXtest(false), pollTimer(this)  {    int xtestEventBase;    int xtestErrorBase;    int major, minor;    if (XTestQueryExtension(dpy, &xtestEventBase,                            &xtestErrorBase, &major, &minor)) {      XTestGrabControl(dpy, True);      vlog.info("XTest extension present - version %d.%d",major,minor);      haveXtest = true;    } else {      vlog.info("XTest extension not present");      vlog.info("unable to inject events or display while server is grabbed");    }  }  virtual ~XDesktop() {    stop();  }  // -=- SDesktop interface  virtual void start(VNCServer* vs) {    int dpyWidth = DisplayWidth(dpy, DefaultScreen(dpy));    int dpyHeight = DisplayHeight(dpy, DefaultScreen(dpy));    Visual* vis = DefaultVisual(dpy, DefaultScreen(dpy));    image = new Image(dpy, dpyWidth, dpyHeight);    image->get(DefaultRootWindow(dpy));    pf.bpp = image->xim->bits_per_pixel;    pf.depth = image->xim->depth;    pf.bigEndian = (image->xim->byte_order == MSBFirst);    pf.trueColour = (vis->c_class == TrueColor);    pf.redShift   = ffs(vis->red_mask) - 1;    pf.greenShift = ffs(vis->green_mask) - 1;    pf.blueShift  = ffs(vis->blue_mask) - 1;    pf.redMax     = vis->red_mask   >> pf.redShift;    pf.greenMax   = vis->green_mask >> pf.greenShift;    pf.blueMax    = vis->blue_mask  >> pf.blueShift;    pb = new FullFramePixelBuffer(pf, dpyWidth, dpyHeight,                                  (rdr::U8*)image->xim->data, this);    server = vs;    server->setPixelBuffer(pb);    pollTimer.start(50);  }  virtual void stop() {    pollTimer.stop();    delete pb;    delete image;  }  virtual void pointerEvent(const Point& pos, int buttonMask) {    if (!haveXtest) return;    XTestFakeMotionEvent(dpy, DefaultScreen(dpy), pos.x, pos.y, CurrentTime);    if (buttonMask != oldButtonMask) {      for (int i = 0; i < 5; i++) {	if ((buttonMask ^ oldButtonMask) & (1<<i)) {          if (buttonMask & (1<<i)) {            XTestFakeButtonEvent(dpy, i+1, True, CurrentTime);          } else {            XTestFakeButtonEvent(dpy, i+1, False, CurrentTime);          }        }      }    }    oldButtonMask = buttonMask;  }  virtual void keyEvent(rdr::U32 key, bool down) {    if (!haveXtest) return;    int keycode = XKeysymToKeycode(dpy, key);    if (keycode)      XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);  }  virtual void clientCutText(const char* str, int len) {  }  virtual Point getFbSize() {    return Point(pb->width(), pb->height());  }  // -=- ColourMap callbacks  virtual void lookup(int index, int* r, int* g, int* b) {    XColor xc;    xc.pixel = index;    if (index < DisplayCells(dpy,DefaultScreen(dpy))) {      XQueryColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), &xc);    } else {      xc.red = xc.green = xc.blue = 0;    }    *r = xc.red;    *g = xc.green;    *b = xc.blue;  }  // -=- Timer::Callback interface  virtual bool handleTimeout(Timer* t) {    if (server->clientsReadyForUpdate()) {      image->get(DefaultRootWindow(dpy));      server->add_changed(pb->getRect());      server->tryUpdate();    }    return true;  }protected:  Display* dpy;  PixelFormat pf;  PixelBuffer* pb;  VNCServer* server;  Image* image;  int oldButtonMask;  bool haveXtest;  Timer pollTimer;};char* programName;static void usage(){  fprintf(stderr, "\nusage: %s [<parameters>]\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);}int main(int argc, char** argv){  initStdIOLoggers();  LogWriter::setLogParams("*:stderr:30");  programName = argv[0];  Display* dpy;  for (int i = 1; i < argc; i++) {    if (Configuration::setParam(argv[i]))      continue;    if (argv[i][0] == '-') {      if (i+1 < argc) {        if (Configuration::setParam(&argv[i][1], argv[i+1])) {          i++;          continue;        }      }      usage();    }    usage();  }  CharArray dpyStr(displayname.getData());  if (!(dpy = XOpenDisplay(dpyStr.buf[0] ? dpyStr.buf : 0))) {    fprintf(stderr,"%s: unable to open display \"%s\"\r\n",            programName, XDisplayName(displayname.getData()));    exit(1);  }  signal(SIGHUP, CleanupSignalHandler);  signal(SIGINT, CleanupSignalHandler);  signal(SIGTERM, CleanupSignalHandler);  try {    TXWindow::init(dpy,"x0vncserver");    XDesktop desktop(dpy);    VNCServerST server("x0vncserver", &desktop);    QueryConnHandler qcHandler(dpy, &server);    server.setQueryConnectionHandler(&qcHandler);    TcpListener listener((int)rfbport);    vlog.info("Listening on port %d", (int)rfbport);    while (true) {      struct timeval tv;      struct timeval* tvp = 0;      fd_set rfds;      std::list<Socket*> sockets;      std::list<Socket*>::iterator i;      // Process any incoming X events      TXWindow::handleXEvents(dpy);            // Process expired timers and get the time until the next one      int timeoutMs = Timer::checkTimeouts();      soonestTimeout(&timeoutMs, server.checkTimeouts());      if (timeoutMs) {        tv.tv_sec = timeoutMs / 1000;        tv.tv_usec = (timeoutMs % 1000) * 1000;        tvp = &tv;      }          // Wait for X events, VNC traffic, or the next timer expiry      // NB: This code assumes that:      //   - removeSocket cannot cause the next timer to become sooner      //   - removeSocket cannot cause other sockets to shutdown()      FD_ZERO(&rfds);      FD_SET(listener.getFd(), &rfds);      FD_SET(ConnectionNumber(dpy), &rfds);      server.getSockets(&sockets);      for (i = sockets.begin(); i != sockets.end(); i++) {        if ((*i)->isShutdown()) {          server.removeSocket(*i);          delete (*i);        } else {          FD_SET((*i)->getFd(), &rfds);        }      }            // If there are X requests pending then poll, don't wait!      if (XPending(dpy)) {        tv.tv_usec = tv.tv_sec = 0;        tvp = &tv;      }            // Do the wait...      int n = select(FD_SETSIZE, &rfds, 0, 0, &tv);      if (n < 0) throw rdr::SystemException("select",errno);      // Accept new VNC connections      if (FD_ISSET(listener.getFd(), &rfds)) {        Socket* sock = listener.accept();        if (sock) server.addSocket(sock);      }      // Process events on existing VNC connections      for (i = sockets.begin(); i != sockets.end(); i++) {        if (FD_ISSET((*i)->getFd(), &rfds))          server.processSocketEvent(*i);      }    }  } catch (rdr::Exception &e) {    vlog.error(e.str());  };  return 0;}

⌨️ 快捷键说明

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