00001 #include "krfbconnection.h"
00002 #include "krfblogin.h"
00003 #include "krfbdecoder.h"
00004 #include "krfbbuffer.h"
00005
00006
00007 #include <opie2/odebug.h>
00008 using namespace Opie::Core;
00009
00010
00011 #include <qsocket.h>
00012 #include <qtimer.h>
00013
00014
00015 #include <assert.h>
00016 #include <string.h>
00017
00018 KRFBConnection::KRFBConnection( QObject *parent )
00019 : QObject( parent, "KRFBConnection" )
00020 {
00021 portBase_ = 5900;
00022 currentState_ = Disconnected;
00023 sock = 0;
00024 minData_ = 0;
00025 options_ = new KRFBServer();
00026 updater = 0;
00027 decoder_ = 0;
00028 buffer_ = 0;
00029 }
00030
00031 KRFBConnection::~KRFBConnection()
00032 {
00033 if ( ( currentState_ != Disconnected ) && ( currentState_ != Disconnecting ) && sock ) {
00034 disconnectDone();
00035 }
00036 delete options_;
00037 }
00038
00039 void KRFBConnection::connectTo( KRFBServer server)
00040 {
00041 if ( currentState_ != Disconnected )
00042 disconnect();
00043
00044 (*options_)=server;
00045
00046 sock = new QSocket( this, "rfbSocket" );
00047 CHECK_PTR( sock );
00048
00049
00050 connect( sock, SIGNAL( error(int) ), SLOT( gotSocketError(int) ) );
00051 connect( sock, SIGNAL( connected() ), SLOT( gotSocketConnection() ) );
00052
00053 owarn << "Connecting..." << oendl;
00054
00055 currentState_ = Connecting;
00056 sock->connectToHost( options_->hostname.latin1(), portBase_ + options_->display );
00057 }
00058
00059 void KRFBConnection::disconnect()
00060 {
00061 owarn << "Disconnecting from server" << oendl;
00062
00063 if ( ( currentState_ != Disconnected )
00064 && ( currentState_ != Disconnecting )
00065 && sock ) {
00066 currentState_ = Disconnecting;
00067
00068 connect( sock, SIGNAL( delayedCloseFinished() ), SLOT( disconnectDone() ) );
00069 sock->close();
00070
00071 if ( sock->state() != QSocket::Closing )
00072 disconnectDone();
00073 }
00074 }
00075
00076 void KRFBConnection::disconnectDone()
00077 {
00078 currentState_ = Disconnected;
00079 delete sock;
00080 sock = 0;
00081 minData_ = 0;
00082 delete updater;
00083 delete decoder_;
00084 delete buffer_;
00085 emit disconnected();
00086 }
00087
00088 void KRFBConnection::gotSocketConnection()
00089 {
00090 currentState_ = LoggingIn;
00091
00092 owarn << "Connected, logging in..." << oendl;
00093
00094 static QString statusMsg = tr( "Connected" );
00095 emit statusChanged( statusMsg );
00096
00097
00098 login = new KRFBLogin( this );
00099 }
00100
00101 void KRFBConnection::gotRFBConnection()
00102 {
00103 owarn << "Logged into server" << oendl;
00104
00105 currentState_ = Connected;
00106 emit connected();
00107
00108
00109 decoder_ = new KRFBDecoder( this );
00110 CHECK_PTR( decoder_ );
00111
00112 buffer_ = new KRFBBuffer( decoder_, this, "RFB Buffer" );
00113 CHECK_PTR( buffer_ );
00114 decoder_->setBuffer( buffer_ );
00115
00116 connect( decoder_, SIGNAL( status(const QString&) ),
00117 this, SIGNAL( statusChanged(const QString&) ) );
00118 emit loggedIn();
00119
00120 decoder_->start();
00121
00122 updater = new QTimer;
00123 connect( updater, SIGNAL( timeout() ), SLOT( updateTimer() ) );
00124 updater->start( options_->updateRate );
00125 }
00126
00127 void KRFBConnection::gotSocketError( int err )
00128 {
00129 currentState_ = Error;
00130
00131
00132 owarn << "KRFBConnection: Socket error " << err << "" << oendl;
00133
00134 static QString refused = tr( "Connection Refused" );
00135 static QString host = tr( "Host not found" );
00136 static QString read = tr( "Read Error: QSocket reported an error reading\n"
00137 "data, the remote host has probably dropped the\n"
00138 "connection." );
00139 static QString confused = tr( "QSocket reported an invalid error code" );
00140
00141 QString msg;
00142 switch ( err ) {
00143 case QSocket::ErrConnectionRefused:
00144 msg = refused;
00145 break;
00146 case QSocket::ErrHostNotFound:
00147 msg = host;
00148 break;
00149 case QSocket::ErrSocketRead:
00150 msg = read;
00151 break;
00152 default:
00153 msg = confused;
00154 };
00155
00156 QObject::disconnect( sock, SIGNAL( readyRead() ), this, SLOT( gotMoreData() ) );
00157 delete sock;
00158 sock = 0;
00159 currentState_ = Disconnected;
00160
00161 emit error( msg );
00162 }
00163
00164 void KRFBConnection::gotMoreData()
00165 {
00166 assert( minData_ > 0 );
00167
00168 if ( sock->size() >= minData_ ) {
00169 minData_ = 0;
00170 QObject::disconnect( sock, SIGNAL( readyRead() ), this, SLOT( gotMoreData() ) );
00171 emit gotEnoughData();
00172 }
00173 }
00174
00175 void KRFBConnection::waitForData( unsigned int sz )
00176 {
00177 assert( minData_ == 0 );
00178 assert( sz > 0 );
00179 assert( currentState_ != Error );
00180
00181 if ( sock->size() >= sz ) {
00182
00183 emit gotEnoughData();
00184 }
00185 else {
00186
00187 minData_ = sz;
00188 connect( sock, SIGNAL( readyRead() ), SLOT( gotMoreData() ) );
00189 }
00190 }
00191
00192 int KRFBConnection::read( void *buf, int sz )
00193 {
00194 return sock->readBlock( (char *) buf, sz );
00195 }
00196
00197 int KRFBConnection::write( void *buf, int sz )
00198 {
00199 return sock->writeBlock( (const char *) buf, sz );
00200 }
00201
00202 KRFBConnection::State KRFBConnection::state() const
00203 {
00204 return currentState_;
00205 }
00206
00207 void KRFBConnection::setPortBase( int base )
00208 {
00209 portBase_ = base;
00210 }
00211
00212 int KRFBConnection::portBase() const
00213 {
00214 return portBase_;
00215 }
00216
00217 void KRFBConnection::updateTimer()
00218 {
00219 decoder_->sendUpdateRequest( true );
00220 }
00221
00222 void KRFBConnection::refresh()
00223 {
00224 decoder_->sendUpdateRequest( false );
00225 }
00226
00227 void KRFBConnection::sendCutText( const QString &text )
00228 {
00229 decoder_->sendCutEvent( text );
00230 }
00231
00232 const QUrl &KRFBConnection::url()
00233 {
00234 url_.setProtocol( "vnc" );
00235 url_.setPort( display() );
00236 url_.setHost( host() );
00237 url_.setPath( "/" );
00238
00239 return url_;
00240 }