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

📄 vncextinit.cc

📁 Informix Table extraction queries have been optimized
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* 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>extern "C" {#define class c_class#define NEED_EVENTS#include "X.h"#include "Xproto.h"#include "misc.h"#include "os.h"#include "dixstruct.h"#include "extnsionst.h"#include "scrnintstr.h"#include "selection.h"#define _VNCEXT_SERVER_#define _VNCEXT_PROTO_#include "vncExt.h"#undef class#undef xalloc}#include <rfb/Configuration.h>#include <rfb/Logger_stdio.h>#include <rfb/LogWriter.h>#include <rfb/util.h>#include <rfb/ServerCore.h>#include <rfb/SSecurityFactoryStandard.h>#include <rdr/HexOutStream.h>#include <rfb/LogWriter.h>#undef max#undef min#include <network/TcpSocket.h>#include "XserverDesktop.h"#include "vncHooks.h"#include "vncExtInit.h"extern "C" {  extern void vncExtensionInit();  static void vncResetProc(ExtensionEntry* extEntry);  static void vncBlockHandler(pointer data, OSTimePtr t, pointer readmask);  static void vncWakeupHandler(pointer data, int nfds, pointer readmask);  static void vncClientStateChange(CallbackListPtr*, pointer, pointer);  static void SendSelectionChangeEvent(Atom selection);  static int ProcVncExtDispatch(ClientPtr client);  static int SProcVncExtDispatch(ClientPtr client);  extern char *display;  extern Selection *CurrentSelections;  extern int NumCurrentSelections;}using namespace rfb;static rfb::LogWriter vlog("vncext");static unsigned long vncExtGeneration = 0;static bool initialised = false;static XserverDesktop* desktop[MAXSCREENS] = { 0, };void* vncFbptr[MAXSCREENS] = { 0, };static char* clientCutText = 0;static int clientCutTextLen = 0;static XserverDesktop* queryConnectDesktop = 0;static void* queryConnectId = 0;static int queryConnectTimeout = 0;static OsTimerPtr queryConnectTimer = 0;static struct VncInputSelect* vncInputSelectHead = 0;struct VncInputSelect {  VncInputSelect(ClientPtr c, Window w, int m) : client(c), window(w), mask(m)  {    next = vncInputSelectHead;    vncInputSelectHead = this;  }  ClientPtr client;  Window window;  int mask;  VncInputSelect* next;};static int nPrevSelections = 0;static TimeStamp* prevSelectionTimes = 0;static int vncErrorBase = 0;static int vncEventBase = 0;static char* vncPasswdFile = 0;int vncInetdSock = -1;rfb::AliasParameter rfbauth("rfbauth", "Alias for PasswordFile",                            &SSecurityFactoryStandard::vncAuthPasswdFile);rfb::StringParameter httpDir("httpd",                             "Directory containing files to serve via HTTP",                             "");rfb::IntParameter httpPort("httpPort", "TCP port to listen for HTTP",0);rfb::AliasParameter rfbwait("rfbwait", "Alias for ClientWaitTimeMillis",                            &rfb::Server::clientWaitTimeMillis);rfb::IntParameter rfbport("rfbport", "TCP port to listen for RFB protocol",0);rfb::StringParameter desktopName("desktop", "Name of VNC desktop","x11");rfb::BoolParameter localhostOnly("localhost",                                 "Only allow connections from localhost",                                 false);void vncExtensionInit(){  if (vncExtGeneration == serverGeneration) {    vlog.error("vncExtensionInit: called twice in same generation?");    return;  }  vncExtGeneration = serverGeneration;  ExtensionEntry* extEntry    = AddExtension(VNCEXTNAME, VncExtNumberEvents, VncExtNumberErrors,                   ProcVncExtDispatch, SProcVncExtDispatch, vncResetProc,                   StandardMinorOpcode);  if (!extEntry) {    ErrorF("vncExtInit: AddExtension failed\n");    return;  }  vncErrorBase = extEntry->errorBase;  vncEventBase = extEntry->eventBase;  vlog.info("VNC extension running!");  if (!AddCallback(&ClientStateCallback, vncClientStateChange, 0)) {    FatalError("AddCallback failed\n");  }  try {    if (!initialised) {      rfb::initStdIOLoggers();      initialised = true;    }    for (int scr = 0; scr < screenInfo.numScreens; scr++) {      if (!desktop[scr]) {        network::TcpListener* listener = 0;        network::TcpListener* httpListener = 0;        if (scr == 0 && vncInetdSock != -1) {          if (network::TcpSocket::isSocket(vncInetdSock) &&              !network::TcpSocket::isConnected(vncInetdSock))          {            listener = new network::TcpListener(0, 0, vncInetdSock, true);            vlog.info("inetd wait");          }        } else {          int port = rfbport;          if (port == 0) port = 5900 + atoi(display);          port += 1000 * scr;          listener = new network::TcpListener(port, localhostOnly);          vlog.info("Listening for VNC connections on port %d",port);          CharArray httpDirStr(httpDir.getData());          if (httpDirStr.buf[0]) {            port = httpPort;            if (port == 0) port = 5800 + atoi(display);            port += 1000 * scr;            httpListener = new network::TcpListener(port, localhostOnly);            vlog.info("Listening for HTTP connections on port %d",port);          }        }        CharArray desktopNameStr(desktopName.getData());        desktop[scr] = new XserverDesktop(screenInfo.screens[scr], listener,                                          httpListener,                                          desktopNameStr.buf,                                          vncFbptr[scr]);        vlog.info("created VNC server for screen %d", scr);        if (scr == 0 && vncInetdSock != -1 && !listener) {          network::Socket* sock = new network::TcpSocket(vncInetdSock);          desktop[scr]->addClient(sock, false);          vlog.info("added inetd sock");        }      } else {        desktop[scr]->serverReset(screenInfo.screens[scr]);      }      vncHooksInit(screenInfo.screens[scr], desktop[scr]);    }    RegisterBlockAndWakeupHandlers(vncBlockHandler, vncWakeupHandler, 0);  } catch (rdr::Exception& e) {    vlog.error("vncExtInit: %s",e.str());  }}static void vncResetProc(ExtensionEntry* extEntry){}//// vncBlockHandler - called just before the X server goes into select().  Call// on to the block handler for each desktop.  Then check whether any of the// selections have changed, and if so, notify any interested X clients.//static void vncBlockHandler(pointer data, OSTimePtr timeout, pointer readmask){  fd_set* fds = (fd_set*)readmask;  for (int scr = 0; scr < screenInfo.numScreens; scr++) {    if (desktop[scr]) {      desktop[scr]->blockHandler(fds);    }  }  if (nPrevSelections != NumCurrentSelections) {    prevSelectionTimes      = (TimeStamp*)xnfrealloc(prevSelectionTimes,                               NumCurrentSelections * sizeof(TimeStamp));    for (int i = nPrevSelections; i < NumCurrentSelections; i++) {      prevSelectionTimes[i].months = 0;      prevSelectionTimes[i].milliseconds = 0;    }    nPrevSelections = NumCurrentSelections;  }  for (int i = 0; i < NumCurrentSelections; i++) {    if (CurrentSelections[i].lastTimeChanged.months        != prevSelectionTimes[i].months ||        CurrentSelections[i].lastTimeChanged.milliseconds        != prevSelectionTimes[i].milliseconds)    {      SendSelectionChangeEvent(CurrentSelections[i].selection);      prevSelectionTimes[i] = CurrentSelections[i].lastTimeChanged;    }  }}static void vncWakeupHandler(pointer data, int nfds, pointer readmask){  fd_set* fds = (fd_set*)readmask;  for (int scr = 0; scr < screenInfo.numScreens; scr++) {    if (desktop[scr]) {      desktop[scr]->wakeupHandler(fds, nfds);    }  }}static void vncClientStateChange(CallbackListPtr*, pointer, pointer p){  ClientPtr client = ((NewClientInfoRec*)p)->client;  if (client->clientState == ClientStateGone) {    VncInputSelect** nextPtr = &vncInputSelectHead;    for (VncInputSelect* cur = vncInputSelectHead; cur; cur = *nextPtr) {      if (cur->client == client) {        *nextPtr = cur->next;        delete cur;        continue;      }      nextPtr = &cur->next;    }  }}void vncBell(){  for (int scr = 0; scr < screenInfo.numScreens; scr++) {    if (desktop[scr]) {      desktop[scr]->bell();    }  }}void vncClientGone(int fd){  if (fd == vncInetdSock) {    fprintf(stderr,"inetdSock client gone\n");    GiveUp(0);  }}void vncClientCutText(const char* str, int len){  delete [] clientCutText;  clientCutText = new char[len];  memcpy(clientCutText, str, len);  clientCutTextLen = len;  xVncExtClientCutTextNotifyEvent ev;  ev.type = vncEventBase + VncExtClientCutTextNotify;  for (VncInputSelect* cur = vncInputSelectHead; cur; cur = cur->next) {    if (cur->mask & VncExtClientCutTextMask) {      ev.sequenceNumber = cur->client->sequence;      ev.window = cur->window;      ev.time = GetTimeInMillis();      if (cur->client->swapped) {        int n;        swaps(&ev.sequenceNumber, n);        swapl(&ev.window, n);        swapl(&ev.time, n);      }      WriteToClient(cur->client, sizeof(xVncExtClientCutTextNotifyEvent),                    (char *)&ev);    }  }}static CARD32 queryConnectTimerCallback(OsTimerPtr timer,                                        CARD32 now, pointer arg){  if (queryConnectTimeout)    queryConnectDesktop->approveConnection(queryConnectId, false, "The attempt to prompt the user to accept the connection failed");  // Re-notify clients, causing them to discover that we're done  vncQueryConnect(queryConnectDesktop, queryConnectId);  return 0;}void vncQueryConnect(XserverDesktop* desktop, void* opaqueId){  // Only one query can be processed at any one time  if (queryConnectTimeout && ((desktop != queryConnectDesktop) ||                              (opaqueId != queryConnectId))) {    desktop->approveConnection(opaqueId, false,                               "Another connection is currently being queried.");    return;  }  // Get the query timeout.  If it's zero, there is no query.  queryConnectTimeout = desktop->getQueryTimeout(opaqueId);  queryConnectId = queryConnectTimeout ? opaqueId : 0;  queryConnectDesktop = queryConnectTimeout ? desktop : 0;  // Notify clients  bool notified = false;  xVncExtQueryConnectNotifyEvent ev;  ev.type = vncEventBase + VncExtQueryConnectNotify;  for (VncInputSelect* cur = vncInputSelectHead; cur; cur = cur->next) {    if (cur->mask & VncExtQueryConnectMask) {      ev.sequenceNumber = cur->client->sequence;      ev.window = cur->window;      if (cur->client->swapped) {        int n;        swaps(&ev.sequenceNumber, n);        swapl(&ev.window, n);      }      WriteToClient(cur->client, sizeof(xVncExtQueryConnectNotifyEvent),                    (char *)&ev);      notified = true;    }  }  // If we're being asked to query a connection (rather than to cancel  //   a query), and haven't been able to notify clients then reject it.  if (queryConnectTimeout && !notified) {    queryConnectTimeout = 0;    queryConnectId = 0;    queryConnectDesktop = 0;    desktop->approveConnection(opaqueId, false,                               "Unable to query the local user to accept the connection.");    return;  }      // Set a timer so that if no-one ever responds, we will eventually   //   reject the connection  //   NB: We don't set a timer if sock is null, since that indicates  //       that pending queries should be cancelled.  if (queryConnectDesktop)    queryConnectTimer = TimerSet(queryConnectTimer, 0,                                 queryConnectTimeout*2000,                                 queryConnectTimerCallback, 0);  else    TimerCancel(queryConnectTimer);}static void SendSelectionChangeEvent(Atom selection){  xVncExtSelectionChangeNotifyEvent ev;  ev.type = vncEventBase + VncExtSelectionChangeNotify;  for (VncInputSelect* cur = vncInputSelectHead; cur; cur = cur->next) {    if (cur->mask & VncExtSelectionChangeMask) {      ev.sequenceNumber = cur->client->sequence;      ev.window = cur->window;      ev.selection = selection;      if (cur->client->swapped) {        int n;        swaps(&ev.sequenceNumber, n);        swapl(&ev.window, n);        swapl(&ev.selection, n);      }      WriteToClient(cur->client, sizeof(xVncExtSelectionChangeNotifyEvent),                    (char *)&ev);    }  }}static int ProcVncExtSetParam(ClientPtr client){  REQUEST(xVncExtSetParamReq);  REQUEST_FIXED_SIZE(xVncExtSetParamReq, stuff->paramLen);  CharArray param(stuff->paramLen+1);  strncpy(param.buf, (char*)&stuff[1], stuff->paramLen);  param.buf[stuff->paramLen] = 0;  xVncExtSetParamReply rep;  int n;  rep.type = X_Reply;  rep.length = 0;  rep.sequenceNumber = client->sequence;  rep.success = rfb::Configuration::setParam(param.buf);  if (client->swapped) {    swaps(&rep.sequenceNumber, n);    swapl(&rep.length, n);  }  WriteToClient(client, sizeof(xVncExtSetParamReply), (char *)&rep);  return (client->noClientException);}static int SProcVncExtSetParam(ClientPtr client){

⌨️ 快捷键说明

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