📄 krfbdecoder.cpp
字号:
} else if ( format->bpp == 16 ) { ushort data; con->read( &data, 2 ); pixel = data; } else if ( format->bpp == 32 ) { ulong data; con->read( &data, 4 ); pixel = Swap32IfLE( data ); } return pixel;}//// Raw Encoding//void KRFBDecoder::handleRawRect(){ // We need something a bit cleverer here to handle large // rectanges nicely. The chunking should be based on the // overall size (but has to be in complete lines). // qWarning( "Handling a raw rect chunk" ); // CARD32 lineCount = w * format->bpp / 8; if ( h > RectChunkSize ) { // if ( con->sock->size() / lineCount ) { // getRawRectChunk( con->sock->size() / lineCount ); // } // else { getRawRectChunk( RectChunkSize ); // } } else { getRawRectChunk( h ); }}void KRFBDecoder::getRawRectChunk( int lines ){ this->lines = lines; CARD32 count = lines * w * format->bpp / 8; // Wait for server init // qWarning( "Waiting for raw rect chunk, %ld", count ); currentState = AwaitingRawRectChunk; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRawRectChunk() ) ); con->waitForData( count );}void KRFBDecoder::gotRawRectChunk(){ assert( currentState == AwaitingRawRectChunk ); disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotRawRectChunk() ) ); // qWarning( "Got raw rect chunk" ); // // Read the rect data and copy it to the buffer. // // TODO: Replace this! int count = lines * w * format->bpp / 8; char *hack = new char[ count ]; con->read( hack, count ); buf->drawRawRectChunk( hack, x, y, w, lines ); delete hack; // /TODO: h = h - lines; y = y + lines; if ( h > 0 ) { handleRawRect(); } else { noRects--; // qWarning( "There are %d rects left", noRects ); if ( noRects ) { currentState = AwaitingRectHeader; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); con->waitForData( RectHeaderLength ); } else currentState = Idle; }}//// Copy Rectangle Encoding//void KRFBDecoder::handleCopyRect(){ currentState = AwaitingCopyRectPos; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotCopyRectPos() ) ); con->waitForData( CopyRectPosLength );}void KRFBDecoder::gotCopyRectPos(){ disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotCopyRectPos() ) ); CARD16 srcX; CARD16 srcY; con->read( &srcX, 2 ); con->read( &srcY, 2 ); srcX = Swap16IfLE( srcX ); srcY = Swap16IfLE( srcY ); buf->copyRect( srcX, srcY, x, y, w, h ); noRects--; // qWarning( "There are %d rects left", noRects ); if ( noRects ) { currentState = AwaitingRectHeader; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); con->waitForData( RectHeaderLength ); } else currentState = Idle;}void KRFBDecoder::handleRRERect(){ if ( currentState == AwaitingRRECount ) { CARD32 tmp32; con->read( &tmp32, 4 ); rreRects = Swap32IfLE( tmp32 ); ulong pixel = readPixel(); buf->fillRect( x, y, w, h, pixel ); if ( rreRects ) currentState = AwaitingRRERect; } if ( currentState == AwaitingRRERect ) { int bytesNeeded = (rreMode == RRE?8:4)+format->bpp/8; while ( rreRects && con->bytesAvailable() >= bytesNeeded ) { ulong pixel; pixel = readPixel(); int rx, ry, rw, rh; if ( rreMode == RRE ) { CARD16 tmp16; con->read( &tmp16, 2 ); rx = Swap16IfLE( tmp16 ); con->read( &tmp16, 2 ); ry = Swap16IfLE( tmp16 ); con->read( &tmp16, 2 ); rw = Swap16IfLE( tmp16 ); con->read( &tmp16, 2 ); rh = Swap16IfLE( tmp16 ); } else { uchar tmp8; con->read( &tmp8, 1 ); rx = tmp8; con->read( &tmp8, 1 ); ry = tmp8; con->read( &tmp8, 1 ); rw = tmp8; con->read( &tmp8, 1 ); rh = tmp8; } buf->fillRect( x+rx, y+ry, rw, rh, pixel ); rreRects--; } } if ( rreRects ) { con->waitForData( (rreMode == RRE?8:4)+format->bpp/8 ); } else { buf->updateDone( x, y, w, h ); disconnect( con, SIGNAL(gotEnoughData()), this, SLOT(handleRRERect()) ); noRects--; if ( noRects ) { currentState = AwaitingRectHeader; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); con->waitForData( RectHeaderLength ); } else { currentState = Idle; } }}void KRFBDecoder::handleHexTileRect(){ int dataNeeded = 0; do { if ( currentState == AwaitingHexEncoding ) { hexRects = 0; uchar enc; con->read( &enc, 1 ); hexEncoding = (HexEncoding)enc; dataNeeded = 0; if ( hexEncoding & Raw ) { int rw = QMIN(16,w); int rh = QMIN(16,h); dataNeeded = rw * rh * format->bpp/8; } else { if ( hexEncoding & BGSpecified ) dataNeeded += format->bpp/8; if ( hexEncoding & FGSpecified ) dataNeeded += format->bpp/8; if ( hexEncoding & AnySubrects ) dataNeeded += 1; } currentState = AwaitingHexData; } else if ( currentState == AwaitingHexData ) { int rw = QMIN(16,w-subX); int rh = QMIN(16,h-subY); uchar tmp8; if ( hexEncoding & Raw ) { static char buffer[ 16*16*4 ]; con->read( buffer, rw*rh*format->bpp/8 ); buf->drawRawRectChunk( buffer, x+subX, y+subY, rw, rh ); } else { if ( hexEncoding & BGSpecified ) { hexBG = readPixel(); } if ( hexEncoding & FGSpecified ) { hexFG = readPixel(); } if ( hexEncoding & AnySubrects ) { con->read( &tmp8, 1 ); hexRects = tmp8; } } if ( hexRects ) { currentState = AwaitingHexSubRect; dataNeeded = 2; if ( hexEncoding & SubrectsColoured ) dataNeeded += format->bpp/8; dataNeeded *= hexRects; buf->fillRect( x+subX, y+subY, rw, rh, hexBG ); buf->updateDone( x+subX, y+subY, rw, rh ); } else { if ( !(hexEncoding & Raw) ) { buf->fillRect( x+subX, y+subY, rw, rh, hexBG ); buf->updateDone( x+subX, y+subY, rw, rh ); } dataNeeded = 1; currentState = AwaitingHexEncoding; subX += 16; if ( subX >= w ) { subX = 0; subY += 16; if ( subY >= h ) { dataNeeded = 0; break; } } } } else if ( currentState == AwaitingHexSubRect ) { for ( int i = 0; i < hexRects; i++ ) { ulong pixel = hexFG; if ( hexEncoding & SubrectsColoured ) { pixel = readPixel(); } uchar tmp8; con->read( &tmp8, 1 ); int rx = tmp8 >> 4; int ry = tmp8 & 0x0f; con->read( &tmp8, 1 ); int rw = tmp8 >> 4; int rh = tmp8 & 0x0f; buf->fillRect( x+subX+rx, y+subY+ry, rw+1, rh+1, pixel ); buf->updateDone( x+subX+rx, y+subY+ry, rw+1, rh+1 ); } dataNeeded = 1; currentState = AwaitingHexEncoding; subX += 16; if ( subX >= w ) { subX = 0; subY += 16; if ( subY >= h ) { dataNeeded = 0; break; } } } } while ( (dataNeeded || !hexEncoding) && con->bytesAvailable() >= dataNeeded ); if ( !dataNeeded ) { disconnect( con, SIGNAL(gotEnoughData()), this, SLOT(handleHexTileRect()) ); noRects--; if ( noRects ) { currentState = AwaitingRectHeader; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) ); con->waitForData( RectHeaderLength ); } else { currentState = Idle; } } else { con->waitForData( dataNeeded ); }}void KRFBDecoder::sendMouseEvent( QMouseEvent *e ){ // Deal with the buttons if ( e->type() != QEvent::MouseMove ) { buttonMask = 0; if ( e->type() == QEvent::MouseButtonPress ) { if ( e->button() & LeftButton ) buttonMask |= 0x01; if ( e->button() & MidButton ) buttonMask |= 0x04; if ( e->button() & RightButton ) buttonMask |= 0x02; } else if ( e->type() == QEvent::MouseButtonRelease ) { if ( e->button() & LeftButton ) buttonMask &= 0x06; if ( e->button() & MidButton ) buttonMask |= 0x03; if ( e->button() & RightButton ) buttonMask |= 0x05; } } CARD16 x = Swap16IfLE( e->x() ); CARD16 y = Swap16IfLE( e->y() ); con->write( &PointerEventId, 1 ); con->write( &buttonMask, 1 ); con->write( &x, 2 ); con->write( &y, 2 );}void KRFBDecoder::sendCutEvent( const QString &unicode ){ // // Warning: There is a bug in the RFB protocol because there is no way to find // out the codepage in use on the remote machine. This could be fixed by requiring // the remote server to use utf8 etc. but for now we have to assume they're the // same. I've reported this problem to the ORL guys, but they apparantly have no // immediate plans to fix the issue. :-( (rich) // CARD8 padding[3]; QCString text = unicode.local8Bit(); CARD32 length = text.length(); length = Swap32IfLE( length ); con->write( &ClientCutTextId, 1 ); con->write( &padding, 3 ); con->write( &length, 4 ); con->write( text.data(), text.length() );}void KRFBDecoder::gotServerCut(){ qWarning( "Got server cut" ); currentState = AwaitingServerCutLength; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutLength() ) ); con->waitForData( ServerCutLenLength );}void KRFBDecoder::gotServerCutLength(){ assert( currentState = AwaitingServerCutLength ); disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotServerCutLength() ) ); CARD8 padding[3]; con->read( padding, 3 ); con->read( &serverCutTextLen, 4 ); serverCutTextLen = Swap32IfLE( serverCutTextLen ); currentState = AwaitingServerCutText; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerCutText() ) ); con->waitForData( serverCutTextLen );}void KRFBDecoder::gotServerCutText(){ assert( currentState = AwaitingServerCutText ); disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotServerCutText() ) ); // // Warning: There is a bug in the RFB protocol because there is no way to find // out the codepage in use on the remote machine. This could be fixed by requiring // the remote server to use utf8 etc. but for now we have to assume they're the // same. I've reported this problem to the ORL guys, but they apparantly have no // immediate plans to fix the issue. :-( (rich) // char *cutbuf = new char[ serverCutTextLen + 1 ]; CHECK_PTR( cutbuf ); con->read( cutbuf, serverCutTextLen ); cutbuf[ serverCutTextLen ] = '\0'; qWarning( "Server cut: %s", cutbuf ); QString cutText( cutbuf ); // DANGER!! qApp->clipboard()->setText( cutText ); delete cutbuf; // Now wait for the update (again) if ( oldState == AwaitingUpdate ) { currentState = AwaitingUpdate; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) ); con->waitForData( UpdateHeaderLength ); } else if ( oldState == Idle ) { currentState = Idle; } else { qWarning( "Async handled in weird state" ); currentState = oldState; };}void KRFBDecoder::gotBell(){ qWarning( "Got server bell" ); buf->soundBell(); // Now wait for the update (again) if ( oldState == AwaitingUpdate ) { currentState = AwaitingUpdate; connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) ); con->waitForData( UpdateHeaderLength ); } else if ( oldState == Idle ) { currentState = Idle; } else { qWarning( "Async handled in weird state" ); currentState = oldState; };}void KRFBDecoder::sendKeyPressEvent( QKeyEvent *event ){ int key; key = toKeySym( event ); if ( key ) { key = Swap32IfLE( key ); CARD8 mask = true; CARD16 padding = 0; con->write( &KeyEventId, 1 ); con->write( &mask, 1 ); con->write( &padding, 2 ); con->write( &key, 4 ); }}void KRFBDecoder::sendKeyReleaseEvent( QKeyEvent *event ){ int key; key = toKeySym( event ); if ( key ) { key = Swap32IfLE( key ); CARD8 mask = false; CARD16 padding = 0; con->write( &KeyEventId, 1 ); con->write( &mask, 1 ); con->write( &padding, 2 ); con->write( &key, 4 ); }}//// The RFB protocol spec says 'For most ordinary keys, the 'keysym'// is the same as the corresponding ASCII value.', but doesn't// elaborate what the most ordinary keys are. The spec also lists// a set (possibly subset, it's unspecified) of mappings for// "other common keys" (backspace, tab, return, escape, etc).//int KRFBDecoder::toKeySym( QKeyEvent *k ){ // // Try and map these "other common keys" first. // if ((k->key() >= Qt::Key_Escape) && (k->key() <= Qt::Key_F12)) { for(int i = 0; keyMap[i].keycode != 0; i++) { if (k->key() == keyMap[i].keycode) { return keyMap[i].keysym; } } } // // If these keys aren't matched, return the ascii code and let the // server figure it out. We don't return k->key(), as the data in // key differs between input methods, and we don't want special cases. // return k->ascii();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -