Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

krfbdecoder.cpp

Go to the documentation of this file.
00001 #include "krfbconnection.h"
00002 #include "krfbserverinfo.h"
00003 #include "krfbdecoder.h"
00004 #include "krfbbuffer.h"
00005 
00006 /* OPIE */
00007 #include <opie2/odebug.h>
00008 using namespace Opie::Core;
00009 
00010 /* QT */
00011 #include <qpixmap.h>
00012 
00013 /* STD */
00014 #include <assert.h>
00015 
00016 //
00017 // Endian stuff
00018 //
00019 //#ifndef OPIE_NO_DEBUG
00020 const int endianTest = 1;
00021 //#endif
00022 
00023 #define Swap16IfLE(s) \
00024     (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
00025 
00026 #define Swap32IfLE(l) \
00027     (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \
00028                  (((l) & 0x00ff0000) >> 8)  | \
00029                  (((l) & 0x0000ff00) << 8)  | \
00030                  (((l) & 0x000000ff) << 24))  : (l))
00031 
00032 //
00033 // The lengths of the messages we need to wait for
00034 //
00035 const int ServerInitLength = 24;
00036 const int UpdateHeaderLength = 4;
00037 const int RectHeaderLength = 12;
00038 const int RectChunkSize = 4;
00039 const int CopyRectPosLength = 4;
00040 const int ServerCutLenLength = 7;
00041 
00042 //
00043 // Client -> Server Message Identifiers
00044 //
00045 static CARD8 SetPixelFormatId = 0;
00046 //static CARD8 FixColourMapEntriesId = 1; // Not used
00047 static CARD8 SetEncodingsId = 2;
00048 static CARD8 UpdateRequestId = 3;
00049 static CARD8 KeyEventId = 4;
00050 static CARD8 PointerEventId = 5;
00051 static CARD8 ClientCutTextId = 6;
00052 
00053 //
00054 // Server -> Client Message Identifiers
00055 //
00056 static CARD8 UpdateId = 0;
00057 static CARD8 BellId = 2;
00058 static CARD8 ServerCutId = 3;
00059 
00060 //
00061 // Encoding identifiers
00062 //
00063 static CARD32 RawEncoding = Swap32IfLE( 0 );
00064 static CARD32 CopyRectEncoding = Swap32IfLE(1 );
00065 static CARD32 RreEncoding = Swap32IfLE( 2 );
00066 static CARD32 CorreEncoding = Swap32IfLE( 4 );
00067 static CARD32 HexTileEncoding = Swap32IfLE( 5 );
00068 
00069 static struct {
00070     int keysym;
00071     int keycode;
00072 } keyMap[] = {
00073     { 0xff08, Qt::Key_Backspace },
00074     { 0xff09, Qt::Key_Tab       },
00075     { 0xff0d, Qt::Key_Return    },
00076     { 0xff1b, Qt::Key_Escape    },
00077     { 0xff63, Qt::Key_Insert    },
00078     { 0xffff, Qt::Key_Delete    },
00079     { 0xff50, Qt::Key_Home      },
00080     { 0xff57, Qt::Key_End       },
00081     { 0xff55, Qt::Key_Prior     },
00082     { 0xff56, Qt::Key_Next      },
00083     { 0xff51, Qt::Key_Left      },
00084     { 0xff52, Qt::Key_Up        },
00085     { 0xff53, Qt::Key_Right     },
00086     { 0xff54, Qt::Key_Down      },
00087     { 0xffbe, Qt::Key_F1        },
00088     { 0xffbf, Qt::Key_F2        },
00089     { 0xffc0, Qt::Key_F3        },
00090     { 0xffc1, Qt::Key_F4        },
00091     { 0xffc2, Qt::Key_F5        },
00092     { 0xffc3, Qt::Key_F6        },
00093     { 0xffc4, Qt::Key_F7        },
00094     { 0xffc5, Qt::Key_F8        },
00095     { 0xffc6, Qt::Key_F9        },
00096     { 0xffc7, Qt::Key_F10       },
00097     { 0xffc8, Qt::Key_F11       },
00098     { 0xffc9, Qt::Key_F12       },
00099     { 0xffe1, Qt::Key_Shift     },
00100     { 0xffe2, Qt::Key_Shift     },
00101     { 0xffe3, Qt::Key_Control   },
00102     { 0xffe4, Qt::Key_Control   },
00103     { 0xffe7, Qt::Key_Meta      },
00104     { 0xffe8, Qt::Key_Meta      },
00105     { 0xffe9, Qt::Key_Alt       },
00106     { 0xffea, Qt::Key_Alt       },
00107     { 0, 0 }
00108 };
00109 
00110 
00111 KRFBDecoder::KRFBDecoder( KRFBConnection *con )
00112   : QObject( con, "RFB Decoder" )
00113 {
00114   assert( con );
00115   assert( con->state() == KRFBConnection::Connected );
00116 
00117   this->con = con;
00118   this->buf = 0;
00119   this->info = 0;
00120   this->format = 0;
00121   this->buttonMask = 0;
00122   currentState = Idle;
00123 }
00124 
00125 KRFBDecoder::~KRFBDecoder()
00126 {
00127   if ( info )
00128     delete info;
00129   if ( format )
00130     delete format;
00131 }
00132 
00133 void KRFBDecoder::start()
00134 {
00135   sendClientInit();
00136 }
00137 
00138 void KRFBDecoder::sendClientInit()
00139 {
00140   con->write( &( con->options()->shared ), 1 );
00141 
00142   // Wait for server init
00143   owarn << "Waiting for server init" << oendl;
00144 
00145   static QString statusMsg = tr( "Waiting for server initialization..." );
00146   emit status( statusMsg );
00147 
00148   currentState = AwaitingServerInit;
00149   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerInit() ) );
00150   con->waitForData( ServerInitLength );
00151 }
00152 
00153 void KRFBDecoder::gotServerInit()
00154 {
00155   owarn << "Got server init" << oendl;
00156   disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotServerInit() ) );
00157 
00158   if ( info )
00159     delete info;
00160   info = new KRFBServerInfo;
00161   CHECK_PTR( info );
00162 
00163   con->read( &(info->width), 2 );
00164   info->width = Swap16IfLE( info->width );
00165   con->read( &info->height, 2 );
00166   info->height = Swap16IfLE( info->height );
00167 
00168   con->read( &(info->bpp), 1 );
00169   con->read( &(info->depth), 1 );
00170   con->read( &(info->bigEndian), 1 );
00171   con->read( &(info->trueColor), 1 );
00172 
00173   con->read( &(info->redMax), 2 );
00174   info->redMax = Swap16IfLE( info->redMax );
00175   con->read( &(info->greenMax), 2 );
00176   info->greenMax = Swap16IfLE( info->greenMax );
00177   con->read( &(info->blueMax), 2 );
00178   info->blueMax = Swap16IfLE( info->blueMax );
00179 
00180   con->read( &(info->redShift), 1 );
00181   con->read( &(info->greenShift), 1 );
00182   con->read( &(info->blueShift), 1 );
00183 
00184   con->read( info->padding, 3 );
00185 
00186   con->read( &(info->nameLength), 4 );
00187   info->nameLength = Swap32IfLE( info->nameLength );
00188 
00189   owarn << "Width = " << info->width << ", Height = " << info->height << "" << oendl;
00190   owarn << "Bpp = " << info->bpp << ", Depth = " << info->depth << ", Big = " << info->bigEndian
00191         << ", True = " << info->trueColor << oendl;
00192   owarn << "RedMax = " << info->redMax << ", GreenMax = " << info->greenMax << ", BlueMax = " << info->blueMax << oendl;
00193   owarn << "RedShift = " << info->redShift << ", GreenShift = " << info->greenShift
00194         << ", BlueShift = " << info-> blueShift << oendl;
00195 
00196   buf->resize( info->width/con->options()->scaleFactor, info->height /con->options()->scaleFactor);
00197 
00198   // Wait for desktop name
00199   owarn << "Waiting for desktop name" << oendl;
00200 
00201   static QString statusMsg = tr( "Waiting for desktop name..." );
00202   emit status( statusMsg );
00203 
00204   currentState = AwaitingDesktopName;
00205   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotDesktopName() ) );
00206   con->waitForData( info->nameLength );
00207 }
00208 
00209 void KRFBDecoder::gotDesktopName()
00210 {
00211   assert( info );
00212   assert( currentState == AwaitingDesktopName );
00213 
00214   owarn << "Got desktop name" << oendl;
00215 
00216   disconnect( con, SIGNAL( gotEnoughData() ),
00217           this, SLOT( gotDesktopName() ) );
00218 
00219   char *buf = new char[ info->nameLength + 1 ];
00220   CHECK_PTR( buf );
00221 
00222   con->read( buf, info->nameLength );
00223   buf[ info->nameLength ] = '\0';
00224   info->name = buf;
00225 
00226   owarn << "Desktop: " << info->name.latin1() << "" << oendl;
00227 
00228   delete buf;
00229 
00230   // Get the format we'll really use and tell the server
00231   decidePixelFormat();
00232   sendPixelFormat();
00233   sendAllowedEncodings();
00234   currentState = Idle;
00235 
00236   QString msg;
00237   msg = tr( "Connected to %1" );
00238   msg = msg.arg( info->name );
00239   emit status( msg );
00240 
00241   sendUpdateRequest( false );
00242 }
00243 
00244 void KRFBDecoder::decidePixelFormat()
00245 {
00246   assert( info );
00247 
00248   if ( format )
00249     delete format;
00250   format = new KRFBPixelFormat;
00251   CHECK_PTR( format );
00252 
00253   // What depth do we want?
00254   //
00255   // We'll use the minimum of the remote and local depths, UNLESS an
00256   // eight bit session has been specifically requested by the user.
00257   int screenDepth = QPixmap::defaultDepth();
00258   int bestDepth = ( screenDepth > info->depth ) ? info->depth : screenDepth;
00259   int chosenDepth;
00260 
00261   if ( con->options()->colors256 )
00262     chosenDepth = 8;
00263   else
00264     chosenDepth = bestDepth;
00265 
00266   owarn << "Screen depth=" << screenDepth << ", server depth=" << info->depth
00267         << ", best depth=" << bestDepth << "eight bit " << con->options()->colors256
00268         << ", chosenDepth=" << chosenDepth << oendl;
00269 
00270   format->depth = chosenDepth;
00271 
00272   // If we're using the servers native depth
00273   if ( chosenDepth == info->depth ) {
00274     // Use the servers native format
00275     format->bpp = info->bpp;
00276     //    format->bigEndian = info->bigEndian;
00277     format->bigEndian = true;
00278     format->trueColor = info->trueColor;
00279     format->redMax = info->redMax;
00280     format->greenMax = info->greenMax;
00281     format->blueMax = info->blueMax;
00282     format->redShift = info->redShift;
00283     format->greenShift = info->greenShift;
00284     format->blueShift = info->blueShift;
00285   }
00286   else {
00287     if ( chosenDepth == 8 ) {
00288       format->bpp = 8;
00289       format->bigEndian = true;
00290       format->trueColor = true;
00291       format->redMax = 7;
00292       format->greenMax = 7;
00293       format->blueMax = 3;
00294       format->redShift = 0;
00295       format->greenShift = 3;
00296       format->blueShift = 6;
00297     }
00298   }
00299 
00300   format->redMax = Swap16IfLE( format->redMax );
00301   format->greenMax = Swap16IfLE( format->greenMax );
00302   format->blueMax = Swap16IfLE( format->blueMax );
00303 }
00304 
00305 void KRFBDecoder::sendPixelFormat()
00306 {
00307   static char padding[3];
00308   con->write( &SetPixelFormatId, 1 );
00309   con->write( padding, 3 );
00310 
00311   con->write( &(format->bpp), 1 );
00312   con->write( &(format->depth), 1 );
00313   con->write( &(format->bigEndian), 1 );
00314   con->write( &(format->trueColor), 1 );
00315 
00316   con->write( &(format->redMax), 2 );
00317   con->write( &(format->greenMax), 2 );
00318   con->write( &(format->blueMax), 2 );
00319 
00320   con->write( &(format->redShift), 1 );
00321   con->write( &(format->greenShift), 1 );
00322   con->write( &(format->blueShift), 1 );
00323   con->write( format->padding, 3 ); // Padding
00324 }
00325 
00326 void KRFBDecoder::sendAllowedEncodings()
00327 {
00328   static CARD8 padding[1];
00329   con->write( &SetEncodingsId, 1 );
00330   con->write( padding, 1 );
00331 
00332   CARD16 noEncodings = con->options()->encodings();
00333   noEncodings = Swap16IfLE( noEncodings );
00334   con->write( &noEncodings, 2 );
00335 
00336   if ( con->options()->corre )
00337     con->write( &CorreEncoding, 4 );
00338   if ( con->options()->hexTile )
00339     con->write( &HexTileEncoding, 4 );
00340   if ( con->options()->rre )
00341     con->write( &RreEncoding, 4 );
00342   if ( con->options()->copyrect )
00343     con->write( &CopyRectEncoding, 4 );
00344   // We always support this
00345   con->write( &RawEncoding, 4 );
00346 }
00347 
00348 void KRFBDecoder::sendUpdateRequest( bool incremental )
00349 {
00350   if ( currentState != Idle )
00351     return;
00352 
00353   con->write( &UpdateRequestId, 1 );
00354   con->write( &incremental, 1 );
00355 
00356   static CARD16 x = 0, y = 0;
00357   static CARD16 w = Swap16IfLE( info->width );
00358   static CARD16 h = Swap16IfLE( info->height );
00359 
00360   con->write( &x, 2 );
00361   con->write( &y, 2 );
00362   con->write( &w, 2 );
00363   con->write( &h, 2 );
00364 
00365   // Now wait for the update
00366   currentState = AwaitingUpdate;
00367   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
00368   con->waitForData( UpdateHeaderLength );
00369 }
00370 
00371 void KRFBDecoder::gotUpdateHeader()
00372 {
00373   assert( currentState == AwaitingUpdate );
00374 
00375   //  owarn << "Got update header" << oendl;
00376 
00377   disconnect( con, SIGNAL( gotEnoughData() ),
00378           this, SLOT( gotUpdateHeader() ) );
00379 
00380   CARD8 msgType;
00381   con->read( &msgType, 1 );
00382 
00383   if ( msgType != UpdateId ) {
00384     // We might have a bell or server cut
00385     if ( msgType == ServerCutId ) {
00386       oldState = currentState;
00387       gotServerCut();
00388     }
00389     else if ( msgType == BellId ) {
00390       oldState = currentState;
00391       gotBell();
00392     }
00393     else {
00394       int msg = msgType;
00395       QString protocolError = tr( "Protocol Error: Message Id %1 was "
00396                                     "found when expecting an update "
00397                                     "message." ).arg( msg );
00398       currentState = Error;
00399       emit error( protocolError );
00400     }
00401     return;
00402   }
00403 
00404   CARD8 padding;
00405   con->read( &padding, 1 );
00406 
00407   con->read( &noRects, 2 );
00408   noRects = Swap16IfLE( noRects );
00409 
00410   //  owarn << "Expecting " << noRects << " rects" << oendl;
00411 
00412   // Now wait for the data
00413   currentState = AwaitingRectHeader;
00414   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
00415   con->waitForData( RectHeaderLength );
00416 }
00417 
00418 void KRFBDecoder::gotRectHeader()
00419 {
00420   assert( currentState == AwaitingRectHeader );
00421 
00422   //  owarn << "Got rect header" << oendl;
00423 
00424   disconnect( con, SIGNAL( gotEnoughData() ),
00425           this, SLOT( gotRectHeader() ) );
00426 
00427   con->read( &x, 2 );
00428   x = Swap16IfLE( x );
00429   con->read( &y, 2 );
00430   y = Swap16IfLE( y );
00431 
00432   con->read( &w, 2 );
00433   w = Swap16IfLE( w );
00434   con->read( &h, 2 );
00435   h = Swap16IfLE( h );
00436 
00437   con->read( &encoding, 4 );
00438 
00439   //  CARD32 encodingLocal = Swap32IfLE( encoding );
00440   //  owarn << "Rect: x=" << x << ", y= " << y << ", w=" << w << ", h=" << h
00441   //        << ", encoding= " << encodingLocal << oendl;
00442 
00443   //
00444   // Each encoding needs to be handled differently. Some require
00445   // waiting for more data, but others like a copyrect do not.
00446   // Our constants have already been byte swapped, so we use
00447   // the remote value as is.
00448   //
00449   if ( encoding == RawEncoding ) {
00450       //    owarn << "Raw encoding" << oendl;
00451     handleRawRect();
00452   }
00453   else if ( encoding == CopyRectEncoding ) {
00454 //    owarn << "CopyRect encoding" << oendl;
00455     handleCopyRect();
00456   }
00457   else if ( encoding == RreEncoding ) {
00458     owarn << "RRE encoding" << oendl;
00459     handleRRERect();
00460   }
00461   else if ( encoding == CorreEncoding ) {
00462     owarn << "CoRRE encoding" << oendl;
00463     handleCoRRERect();
00464   }
00465   else if ( encoding == HexTileEncoding ) {
00466     owarn << "HexTile encoding" << oendl;
00467     handleHexTileRect();
00468   }
00469   else {
00470     int msg = Swap32IfLE( encoding );
00471     QString protocolError = tr( "Protocol Error: An unknown encoding was "
00472                   "used by the server %1" ).arg( msg );
00473     currentState = Error;
00474     owarn << "Unknown encoding, " << msg << "" << oendl;
00475     emit error( protocolError );
00476     return;
00477   }
00478 }
00479 
00480 //
00481 // Raw Encoding
00482 //
00483 
00484 void KRFBDecoder::handleRawRect()
00485 {
00486   // We need something a bit cleverer here to handle large
00487   // rectanges nicely. The chunking should be based on the
00488   // overall size (but has to be in complete lines).
00489 
00490     //  owarn << "Handling a raw rect chunk" << oendl;
00491 
00492     //  CARD32 lineCount = w * format->bpp / 8;
00493 
00494   if ( h > RectChunkSize ) {
00495     //    if ( con->sock->size() / lineCount ) {
00496     //      getRawRectChunk( con->sock->size() / lineCount );
00497     //    }
00498     //    else {
00499       getRawRectChunk( RectChunkSize );
00500       //   }
00501   }
00502   else {
00503     getRawRectChunk( h );
00504   }
00505 }
00506 
00507 void KRFBDecoder::getRawRectChunk( int lines )
00508 {
00509   this->lines = lines;
00510   CARD32 count = lines * w * format->bpp / 8;
00511 
00512   // Wait for server init
00513   //  owarn << "Waiting for raw rect chunk, " << count << "" << oendl;
00514 
00515   currentState = AwaitingRawRectChunk;
00516   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRawRectChunk() ) );
00517   con->waitForData( count );
00518 }
00519 
00520 void KRFBDecoder::gotRawRectChunk()
00521 {
00522   assert( currentState == AwaitingRawRectChunk );
00523 
00524   disconnect( con, SIGNAL( gotEnoughData() ),
00525               this, SLOT( gotRawRectChunk() ) );
00526 
00527   //  owarn << "Got raw rect chunk" << oendl;
00528 
00529   //
00530   // Read the rect data and copy it to the buffer.
00531   //
00532 
00533   // TODO: Replace this!
00534   int count = lines * w * format->bpp / 8;
00535   char *hack = new char[ count ];
00536   con->read( hack, count );
00537   buf->drawRawRectChunk( hack, x, y, w, lines );
00538   delete hack;
00539   // /TODO:
00540 
00541   h = h - lines;
00542   y = y + lines;
00543 
00544   if ( h > 0 ) {
00545     handleRawRect();
00546   }
00547   else {
00548     noRects--;
00549 
00550     //    owarn << "There are " << noRects << " rects left" << oendl;
00551 
00552     if ( noRects ) {
00553       currentState = AwaitingRectHeader;
00554       connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
00555       con->waitForData( RectHeaderLength );
00556     }
00557     else {
00558       // we are now ready for the next update - no need to wait for the timer
00559       currentState = Idle;
00560       sendUpdateRequest (1);
00561     }
00562   }
00563 }
00564 
00565 //
00566 // Copy Rectangle Encoding
00567 //
00568 
00569 void KRFBDecoder::handleCopyRect()
00570 {
00571   currentState = AwaitingCopyRectPos;
00572   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotCopyRectPos() ) );
00573   con->waitForData( CopyRectPosLength );
00574 }
00575 
00576 void KRFBDecoder::gotCopyRectPos()
00577 {
00578   disconnect( con, SIGNAL( gotEnoughData() ),
00579               this, SLOT( gotCopyRectPos() ) );
00580 
00581   CARD16 srcX;
00582   CARD16 srcY;
00583 
00584   con->read( &srcX, 2 );
00585   con->read( &srcY, 2 );
00586 
00587   srcX = Swap16IfLE( srcX );
00588   srcY = Swap16IfLE( srcY );
00589 
00590   buf->copyRect( srcX, srcY, x, y, w, h );
00591 
00592   noRects--;
00593 
00594   //    owarn << "There are " << noRects << " rects left" << oendl;
00595 
00596   if ( noRects ) {
00597     currentState = AwaitingRectHeader;
00598     connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );
00599     con->waitForData( RectHeaderLength );
00600   }
00601   else
00602     currentState = Idle;
00603 }
00604 
00605 void KRFBDecoder::handleRRERect()
00606 {
00607   owarn << "RRE not implemented" << oendl;
00608 }
00609 
00610 void KRFBDecoder::handleCoRRERect()
00611 {
00612   owarn << "CoRRE not implemented" << oendl;
00613 }
00614 
00615 void KRFBDecoder::handleHexTileRect()
00616 {
00617   owarn << "HexTile not implemented" << oendl;
00618 }
00619 
00620 void KRFBDecoder::sendMouseEvent( QMouseEvent *e )
00621 {
00622   // Deal with the buttons
00623   if ( e->type() != QEvent::MouseMove ) {
00624     buttonMask = 0;
00625     if ( e->type() == QEvent::MouseButtonPress ) {
00626       if ( e->button() & LeftButton )
00627         buttonMask |= 0x01;
00628       if ( e->button() & MidButton )
00629         buttonMask |= 0x04;
00630       if ( e->button() & RightButton )
00631         buttonMask |= 0x02;
00632     }
00633     else if ( e->type() == QEvent::MouseButtonRelease ) {
00634       if ( e->button() & LeftButton )
00635         buttonMask &= 0x06;
00636       if ( e->button() & MidButton )
00637         buttonMask |= 0x03;
00638       if ( e->button() & RightButton )
00639         buttonMask |= 0x05;
00640     }
00641   }
00642 
00643     // HACK: Scaling
00644   CARD16 x = Swap16IfLE( e->x() * con->options()->scaleFactor );
00645   CARD16 y = Swap16IfLE( e->y() *   con->options()->scaleFactor );
00646 
00647   con->write( &PointerEventId, 1 );
00648   con->write( &buttonMask, 1 );
00649   con->write( &x, 2 );
00650   con->write( &y, 2 );
00651 }
00652 
00653 
00654 void KRFBDecoder::sendCutEvent( const QString &unicode )
00655 {
00656   //
00657   // Warning: There is a bug in the RFB protocol because there is no way to find
00658   // out the codepage in use on the remote machine. This could be fixed by requiring
00659   // the remote server to use utf8 etc. but for now we have to assume they're the
00660   // same. I've reported this problem to the ORL guys, but they apparantly have no
00661   // immediate plans to fix the issue. :-( (rich)
00662   //
00663 
00664   CARD8 padding[3];
00665   QCString text = unicode.local8Bit();
00666   CARD32 length = text.length();
00667   length = Swap32IfLE( length );
00668 
00669   con->write( &ClientCutTextId, 1 );
00670   con->write( &padding, 3 );
00671   con->write( &length, 4 );
00672   con->write( text.data(), length );
00673 }
00674 
00675 void KRFBDecoder::gotServerCut()
00676 {
00677   owarn << "Got server cut" << oendl;
00678 
00679   currentState = AwaitingServerCutLength;
00680   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutLength() ) );
00681   con->waitForData( ServerCutLenLength );
00682 }
00683 
00684 void KRFBDecoder::gotServerCutLength()
00685 {
00686   assert( currentState = AwaitingServerCutLength );
00687   disconnect( con, SIGNAL( gotEnoughData() ),
00688               this, SLOT( gotServerCutLength() ) );
00689 
00690   CARD8 padding[3];
00691   con->read( padding, 3 );
00692 
00693   con->read( &serverCutTextLen, 4 );
00694   serverCutTextLen = Swap32IfLE( serverCutTextLen );
00695 
00696   currentState = AwaitingServerCutText;
00697   connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutText() ) );
00698   con->waitForData( serverCutTextLen );
00699 }
00700 
00701 void KRFBDecoder::gotServerCutText()
00702 {
00703   assert( currentState = AwaitingServerCutText );
00704 
00705   disconnect( con, SIGNAL( gotEnoughData() ),
00706               this, SLOT( gotServerCutText() ) );
00707 
00708 
00709   //
00710   // Warning: There is a bug in the RFB protocol because there is no way to find
00711   // out the codepage in use on the remote machine. This could be fixed by requiring
00712   // the remote server to use utf8 etc. but for now we have to assume they're the
00713   // same. I've reported this problem to the ORL guys, but they apparantly have no
00714   // immediate plans to fix the issue. :-( (rich)
00715   //
00716 
00717   char *cutbuf = new char[ serverCutTextLen + 1 ];
00718   CHECK_PTR( cutbuf );
00719 
00720   con->read( cutbuf, serverCutTextLen );
00721   cutbuf[ serverCutTextLen ] = '\0';
00722 
00723   /* For some reason QApplication::clipboard()->setText() segfaults when called
00724    * from within keypebble's mass of signals and slots
00725   owarn << "Server cut: " << cutbuf << "" << oendl;
00726 
00727   QString cutText( cutbuf ); // DANGER!!
00728   qApp->clipboard()->setText( cutText );
00729   */
00730 
00731   delete cutbuf;
00732   // Now wait for the update (again)
00733   if ( oldState == AwaitingUpdate ) {
00734     currentState = AwaitingUpdate;
00735     connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
00736     con->waitForData( UpdateHeaderLength );
00737   }
00738   else if ( oldState == Idle ) {
00739     currentState = Idle;
00740   }
00741   else {
00742     owarn << "Async handled in weird state" << oendl;
00743     currentState = oldState;
00744   };
00745 }
00746 
00747 void KRFBDecoder::gotBell()
00748 {
00749   owarn << "Got server bell" << oendl;
00750   buf->soundBell();
00751 
00752   // Now wait for the update (again)
00753   if ( oldState == AwaitingUpdate ) {
00754     currentState = AwaitingUpdate;
00755     connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );
00756     con->waitForData( UpdateHeaderLength );
00757   }
00758   else if ( oldState == Idle ) {
00759     currentState = Idle;
00760   }
00761   else {
00762     owarn << "Async handled in weird state" << oendl;
00763     currentState = oldState;
00764   };
00765 }
00766 
00767 void KRFBDecoder::sendKeyPressEvent( QKeyEvent *event )
00768 {
00769   int key;
00770   key = toKeySym( event );
00771   if ( key ) {
00772     key = Swap32IfLE( key );
00773 
00774     CARD8 mask = true;
00775 
00776     CARD16 padding = 0;
00777     con->write( &KeyEventId, 1 );
00778     con->write( &mask, 1 );
00779     con->write( &padding, 2 );
00780     con->write( &key, 4 );
00781   }
00782 }
00783 
00784 void KRFBDecoder::sendKeyReleaseEvent( QKeyEvent *event )
00785 {
00786   int key;
00787   key = toKeySym( event );
00788   if ( key ) {
00789     key = Swap32IfLE( key );
00790 
00791     CARD8 mask = false;
00792 
00793     CARD16 padding = 0;
00794     con->write( &KeyEventId, 1 );
00795     con->write( &mask, 1 );
00796     con->write( &padding, 2 );
00797     con->write( &key, 4 );
00798   }
00799 }
00800 
00801 
00802 
00803 
00804 //
00805 // The RFB protocol spec says 'For most ordinary keys, the 'keysym'
00806 // is the same as the corresponding ASCII value.', but doesn't
00807 // elaborate what the most ordinary keys are.  The spec also lists
00808 // a set (possibly subset, it's unspecified) of mappings for
00809 // "other common keys" (backspace, tab, return, escape, etc).
00810 //
00811 int KRFBDecoder::toKeySym( QKeyEvent *k )
00812 {
00813 
00814     //
00815     // Try and map these "other common keys" first.
00816     //
00817     if ((k->key() >= Qt::Key_Escape) && (k->key() <= Qt::Key_F12)) {
00818     for(int i = 0; keyMap[i].keycode != 0; i++) {
00819         if (k->key() == keyMap[i].keycode) {
00820         return keyMap[i].keysym;
00821         }
00822     }
00823     }
00824 
00825     //
00826     // If these keys aren't matched, return the ascii code and let the
00827     // server figure it out.  We don't return k->key(), as the data in
00828     // key differs between input methods, and we don't want special cases.
00829     //
00830     return k->ascii();
00831 }

Generated on Sat Nov 5 16:17:16 2005 for OPIE by  doxygen 1.4.2