From 902380c42f1a640859c8c93298e40bbe9482aa7e Mon Sep 17 00:00:00 2001 From: Tim Jansen Date: Mon, 17 Dec 2001 02:47:03 +0000 Subject: [PATCH] Sync svn path=/trunk/kdenetwork/krfb/; revision=127504 --- TODO | 1 + krfb/rfbconnection.cpp | 29 +++++++- krfb/rfbconnection.h | 5 +- krfb/rfbcontroller.cpp | 163 +++++++++++++++++++++++++++++++++++++++++ krfb/rfbcontroller.h | 76 +++++++++++++++++++ 5 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 krfb/rfbcontroller.cpp create mode 100644 krfb/rfbcontroller.h diff --git a/TODO b/TODO index 8b137891..3505350d 100644 --- a/TODO +++ b/TODO @@ -1 +1,2 @@ +Possible features: diff --git a/krfb/rfbconnection.cpp b/krfb/rfbconnection.cpp index 6cb9d22d..32b0eec3 100644 --- a/krfb/rfbconnection.cpp +++ b/krfb/rfbconnection.cpp @@ -25,14 +25,21 @@ #include #include #include +#include +#include -RFBConnection::RFBConnection(Display *dpy, int fd) : +RFBConnection::RFBConnection(Display *dpy, int fd, const QString &cpassword) : Server(), dpy(dpy), fd(fd), buttonMask(0) { + memcpy(password, "\0\0\0\0\0\0\0\0", 8); + if (!cpassword.isNull()) + strncpy(password, cpassword.latin1(), + 8 <= cpassword.length() ? 8 : cpassword.length()); + bufferedConnection = new BufferedConnection(32768, 32768); connection = bufferedConnection; @@ -134,3 +141,23 @@ void RFBConnection::destroyFramebuffer() delete scanner; XDestroyImage(framebufferImage); } + +void RFBConnection::scanUpdates() +{ + list hintList; + + scanner->searchUpdates(hintList); + list::iterator i; + for (i = hintList.begin(); i != hintList.end(); i++) + handleHint(*i); +}; + +void RFBConnection::getServerInitialisation( ServerInitialisation &_serverInit ) +{ + Server::getServerInitialisation( _serverInit ); + _serverInit.name_length = strlen( getenv("HOSTNAME") ); + _serverInit.name_string = (CARD8 *) malloc( _serverInit.name_length + 1 ); + strcpy( (char*) _serverInit.name_string, getenv( "HOSTNAME" ) ); +} + +#include "rfbconnection.moc" diff --git a/krfb/rfbconnection.h b/krfb/rfbconnection.h index 290e8808..32be0d90 100644 --- a/krfb/rfbconnection.h +++ b/krfb/rfbconnection.h @@ -25,6 +25,7 @@ // QT must be first because of conflicts with X11 #include +#include #include "XUpdateScanner.h" @@ -49,10 +50,12 @@ using namespace rfb; class RFBConnection : public QObject, public Server { Q_OBJECT public: - RFBConnection(Display *dpy, int fd); + RFBConnection(Display *dpy, int fd, const QString &cpassword); ~RFBConnection(); virtual void handleKeyEvent(KeyEvent &keyEvent); virtual void handlePointerEvent(PointerEvent &pointerEvent); + virtual void getServerInitialisation( ServerInitialisation &_serverInitialisation ); + void scanUpdates(); private: void createFramebuffer(); diff --git a/krfb/rfbcontroller.cpp b/krfb/rfbcontroller.cpp new file mode 100644 index 00000000..5de6fc55 --- /dev/null +++ b/krfb/rfbcontroller.cpp @@ -0,0 +1,163 @@ +/*************************************************************************** + rfbcontroller.cpp + ------------------- + begin : Sun Dec 9 2001 + copyright : (C) 2001 by Tim Jansen + email : tim@tjansen.de + ***************************************************************************/ + +/*************************************************************************** + * Contains portions & concept from rfb's x0rfbserver.cc + * Copyright (C) 2000 heXoNet Support GmbH, D-66424 Homburg. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program 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. * + * * + ***************************************************************************/ + +#include "rfbcontroller.h" + +#include +#include +#include +#include +#include + +RFBController::RFBController(Configuration *c) : + configuration(c), + idleUpdateScheduled(false) +{ + start(); +} + +RFBController::~RFBController() { + delete serversocket; + delete connection; + delete socket; +} + +void RFBController::start() { + serversocket = new KServerSocket(configuration->port, false); + connect(serversocket, SIGNAL(accepted()), SLOT(accepted())); + serversocket->bindAndListen(); + // TODO: error message if bindAndListen fails (port in use) +} + +void RFBController::rebind() { + if (serversocket) { + delete serversocket; + start(); + } +} + +void RFBController::idleSlot() { + idleUpdateScheduled = false; + if (connection) { + connection->sendIncrementalFramebufferUpdate(); + checkWritable(); + } +} + +// called when KServerSocket accepted a connection. Closes KServerSocket. +void RFBController::accepted() { + int sockFd = serversocket->socket; + KSocket s; + if (sockFd < 0) + kdebug("Negative server socket?"); + + int one = 1; + setsockopt(sockFd, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)); + fcntl(sockFd, F_SETFL, O_NONBLOCK); + s = new KSocket(sockFd); + + // TODO: ASK USER FOR PERMISSION HERE BEFORE GOING ON + + delete serversocket; + serversocket = 0; + + socket = s; + connect(s, SIGNAL(readEvent(KSocket*)), SLOT(sockedReadable())); + connect(s, SIGNAL(writeEvent(KSocket*)), SLOT(sockedWritable())); + connect(s, SIGNAL(closeEvent(KSocket*)), SLOT(sockedClosed())); + s.enableRead(true); + connection = new RFBConnection(qt_xdisplay(), sockFd, + configuration->password); + setWritable(); + emit sessionEstablished(); +} + +void RFBController::checkWritable() { + BufferedConnection *bc = connection->bufferedConnection; + socket->writeEnable((bc->senderBuffer.end - bc->senderBuffer.pos) > 0); +} + +void RFBController::prepareIdleUpdate() { + if (!idleUpdateScheduled) + QTimer::singleShot(0, this, SLOT(idleSlot())); + idleUpdateScheduled = true; +} + +void RFBController::socketReadable() { + ASSERT(socket); + int fd = socket->socket(); + BufferedConnection *bc = connection->bufferedConnection; + prepareIdleUpdate(); + int count = read(fd, + bc->receiverBuffer.data, + bc->receiverBuffer.size); + if (count >= 0) + bc->receiverBuffer.end += count; + else { + // TODO: what to do if write failed + } + while (connection->currentState && bc->hasReceiverBufferData()) { + connection->update(); + setWritable(); + } + bc->receiverBuffer.pos = 0; + bc->receiverBuffer.end = 0; + + if (!connection->currentState) + closeSession(); +} + +void RFBController::socketWritable() { + ASSERT(socket); + int fd = socket->socket(); + BufferedConnection *bc = connection->bufferedConnection; + ASSERT((bc->senderBuffer.end - bc->senderBuffer.pos) > 0); + // TODO: what to do if fd < 0? + prepareIdleUpdate(); + int count = write(fd, + bc->senderBuffer.data + bc->senderBuffer.pos, + bc->senderBuffer.end - bc->senderBuffer.pos); + if (count >= 0) + bc->senderBuffer.pos += count; + else { + // TODO: what to do if write failed + } + setWritable(); +} + +void RFBController::closeSession() { + if (!connection) + return; + delete connection; + delete socket; + connection = 0; + socket = 0; + emit sessionFinished(); + start(); +} + +void RFBController::socketClosed() { + closeSession(); +} + +#include "rfbcontroller.moc" diff --git a/krfb/rfbcontroller.h b/krfb/rfbcontroller.h new file mode 100644 index 00000000..44540924 --- /dev/null +++ b/krfb/rfbcontroller.h @@ -0,0 +1,76 @@ +/*************************************************************************** + rfbcontroller.h + ------------------- + begin : Sun Dec 9 2001 + copyright : (C) 2001 by Tim Jansen + email : tim@tjansen.de + ***************************************************************************/ + +/*************************************************************************** + * Contains portions & concept from rfb's x0rfbserver.cc + * Copyright (C) 2000 heXoNet Support GmbH, D-66424 Homburg. + ***************************************************************************/ + +/*************************************************************************** + * * + * This program 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. * + * * + ***************************************************************************/ + +#ifndef RFBCONTROLLER_H +#define RFBCONTROLLER_H + +#include "rfbconnection.h" +#include "configuration.h" +#include +#include +#include + +using namespace rfb; + +/** + * Manages sockets, drives the RGBConnection and triggers the connection + * dialog. + * The controller has two states: 'waiting for connection' and 'connected'. + * In the former serversocket is set and socket and connection are null, in + * the latter serversocket is null and socket and connection are set. + * @author Tim Jansen + */ +class RFBController : public QObject { + Q_OBJECT +public: + RFBController(Configuration *c); + ~RFBController(); + + void closeSession(); + +public slots: + void rebind(); + +signals: + void sessionEstablished(); + void sessionFinished(); + +private: + void start(); + void checkWritable(); + void prepareIdleUpdate(); + + Configuration *c; + KServerSocket *serversocket; + KSocket *socket; + RFBConnection *connection; + bool idleUpdateScheduled; + +private slots: + void idleSlot(); + void accepted(); + void socketReadable(); + void socketWritable(); + void socketClosed(); +}; + +#endif