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

📄 krfbdecoder.cpp

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS and its licensors.** All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.** See below for additional copyright and license information**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "krfbconnection.h"#include "krfboptions.h"#include "krfbserverinfo.h"#include "krfbdecoder.h"#include "krfbbuffer.h"#include <qtopia/qpeapplication.h>#include <qpixmap.h>#include <qsocket.h>#include <qevent.h>#include <qstring.h>#include <qclipboard.h>#include <assert.h>//// Endian stuff//const int endianTest = 1;#define Swap16IfLE(s) \    (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))#define Swap32IfLE(l) \    (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \			     (((l) & 0x00ff0000) >> 8)  | \			     (((l) & 0x0000ff00) << 8)  | \			     (((l) & 0x000000ff) << 24))  : (l))//// The lengths of the messages we need to wait for//const int ServerInitLength = 24;const int UpdateHeaderLength = 4;const int RectHeaderLength = 12;const int RectChunkSize = 4;const int CopyRectPosLength = 4;const int ServerCutLenLength = 7;//// Client -> Server Message Identifiers//static CARD8 SetPixelFormatId = 0;//static CARD8 FixColourMapEntriesId = 1; // Not usedstatic CARD8 SetEncodingsId = 2;static CARD8 UpdateRequestId = 3;static CARD8 KeyEventId = 4;static CARD8 PointerEventId = 5;static CARD8 ClientCutTextId = 6;//// Server -> Client Message Identifiers//static CARD8 UpdateId = 0;static CARD8 BellId = 2;static CARD8 ServerCutId = 3;//// Encoding identifiers//static CARD32 RawEncoding = Swap32IfLE( 0 );static CARD32 CopyRectEncoding = Swap32IfLE(1 );static CARD32 RreEncoding = Swap32IfLE( 2 );static CARD32 CorreEncoding = Swap32IfLE( 4 );static CARD32 HexTileEncoding = Swap32IfLE( 5 );//// Qt -> X11 keysym mappings, in Qt order.  Qt keycodes from <qnamespace.h>;// X11 keysyms from <X11/keysymdef.h>.//static struct {    int keysym;    int keycode;} keyMap[] = {    { 0xff1b, Qt::Key_Escape    },    { 0xff09, Qt::Key_Tab       },    { 0xff08, Qt::Key_Backspace },    { 0xff0d, Qt::Key_Return    },    { 0xff63, Qt::Key_Insert    },    { 0xffff, Qt::Key_Delete    },    { 0xff50, Qt::Key_Home      },    { 0xff57, Qt::Key_End       },    { 0xff51, Qt::Key_Left      },    { 0xff52, Qt::Key_Up        },    { 0xff53, Qt::Key_Right     },    { 0xff54, Qt::Key_Down      },    { 0xff55, Qt::Key_Prior     },    { 0xff56, Qt::Key_Next      },    { 0xffe1, Qt::Key_Shift     },    { 0xffe2, Qt::Key_Shift     },    { 0xffe3, Qt::Key_Control   },    { 0xffe4, Qt::Key_Control   },    { 0xffe7, Qt::Key_Meta      },    { 0xffe8, Qt::Key_Meta      },    { 0xffe9, Qt::Key_Alt       },    { 0xffea, Qt::Key_Alt       },    { 0xffbe, Qt::Key_F1        },    { 0xffbf, Qt::Key_F2        },    { 0xffc0, Qt::Key_F3        },    { 0xffc1, Qt::Key_F4        },    { 0xffc2, Qt::Key_F5        },    { 0xffc3, Qt::Key_F6        },    { 0xffc4, Qt::Key_F7        },    { 0xffc5, Qt::Key_F8        },    { 0xffc6, Qt::Key_F9        },    { 0xffc7, Qt::Key_F10       },    { 0xffc8, Qt::Key_F11       },    { 0xffc9, Qt::Key_F12       },    { 0, 0 }};KRFBDecoder::KRFBDecoder( KRFBConnection *con )  : QObject( con, "RFB Decoder" ) // No tr{  assert( con );  assert( con->state() == KRFBConnection::Connected );  this->con = con;  this->buf = 0;  this->info = 0;  this->format = 0;  this->buttonMask = 0;  currentState = Idle;}KRFBDecoder::~KRFBDecoder(){  if ( info )    delete info;  if ( format )    delete format;}void KRFBDecoder::start(){  sendClientInit();}void KRFBDecoder::sendClientInit(){  con->write( &( con->options()->shared ), 1 );  // Wait for server init  qWarning( "Waiting for server init" );  static QString statusMsg = tr( "Waiting for server initialization..." );  emit status( statusMsg );  currentState = AwaitingServerInit;  connect( con, SIGNAL( gotEnoughData() ), SLOT( gotServerInit() ) );  con->waitForData( ServerInitLength );}void KRFBDecoder::gotServerInit(){  qWarning( "Got server init" );  disconnect( con, SIGNAL( gotEnoughData() ), this, SLOT( gotServerInit() ) );  if ( info )    delete info;  info = new KRFBServerInfo;  CHECK_PTR( info );  con->read( &(info->width), 2 );  info->width = Swap16IfLE( info->width );  con->read( &info->height, 2 );  info->height = Swap16IfLE( info->height );  con->read( &(info->bpp), 1 );  con->read( &(info->depth), 1 );  con->read( &(info->bigEndian), 1 );  con->read( &(info->trueColor), 1 );  con->read( &(info->redMax), 2 );  info->redMax = Swap16IfLE( info->redMax );  con->read( &(info->greenMax), 2 );  info->greenMax = Swap16IfLE( info->greenMax );  con->read( &(info->blueMax), 2 );  info->blueMax = Swap16IfLE( info->blueMax );  con->read( &(info->redShift), 1 );  con->read( &(info->greenShift), 1 );  con->read( &(info->blueShift), 1 );  con->read( info->padding, 3 );  con->read( &(info->nameLength), 4 );  info->nameLength = Swap32IfLE( info->nameLength );  qWarning( "Width = %d, Height = %d", info->width, info->height );  qWarning( "Bpp = %d, Depth = %d, Big = %d, True = %d",	   info->bpp, info->depth, info->bigEndian, info->trueColor );  qWarning( "RedMax = %d, GreenMax = %d, BlueMax = %d",	   info->redMax, info->greenMax, info->blueMax );  qWarning( "RedShift = %d, GreenShift = %d, BlueShift = %d",	   info->redShift, info->greenShift,info-> blueShift );  buf->resize( info->width, info->height );  // Wait for desktop name  qWarning( "Waiting for desktop name" );  static QString statusMsg = tr( "Waiting for desktop name..." );  emit status( statusMsg );  currentState = AwaitingDesktopName;  connect( con, SIGNAL( gotEnoughData() ), SLOT( gotDesktopName() ) );  con->waitForData( info->nameLength );}void KRFBDecoder::gotDesktopName(){  assert( info );  assert( currentState == AwaitingDesktopName );  qWarning( "Got desktop name" );  disconnect( con, SIGNAL( gotEnoughData() ), 	      this, SLOT( gotDesktopName() ) );  char *buf = new char[ info->nameLength + 1 ];  CHECK_PTR( buf );  con->read( buf, info->nameLength );  buf[ info->nameLength ] = '\0';  info->name = buf;  qWarning( "Desktop: %s", info->name.latin1() );  delete buf;  // Get the format we'll really use and tell the server  decidePixelFormat();  sendPixelFormat();  sendAllowedEncodings();  currentState = Idle;  QString msg;  msg = tr( "Connected to %1" );  msg = msg.arg( info->name );  emit status( msg );  sendUpdateRequest( false );}void KRFBDecoder::decidePixelFormat(){  assert( info );  if ( format )    delete format;  format = new KRFBPixelFormat;  CHECK_PTR( format );  // What depth do we want?  //  // We'll use the minimum of the remote and local depths, UNLESS an  // eight bit session has been specifically requested by the user.  int screenDepth = QPixmap::defaultDepth();  int bestDepth = ( screenDepth > info->depth ) ? info->depth : screenDepth;  int chosenDepth;  if ( con->options()->colors256 )    chosenDepth = 8;  else    chosenDepth = bestDepth;  qWarning( "Screen depth=%d, server depth=%d, best depth=%d, " \	   "eight bit %d, chosenDepth=%d",	   screenDepth,	   info->depth,	   bestDepth, 	   con->options()->colors256, chosenDepth );  format->depth = chosenDepth;  // If we're using the servers native depth  if ( chosenDepth == info->depth ) {    // Use the servers native format    format->bpp = info->bpp;    format->bigEndian = (*(char *)&endianTest) ? FALSE : TRUE;    format->trueColor = info->trueColor;    format->redMax = info->redMax;    format->greenMax = info->greenMax;    format->blueMax = info->blueMax;    format->redShift = info->redShift;    format->greenShift = info->greenShift;    format->blueShift = info->blueShift;  }  else {    if ( chosenDepth == 8 ) {      format->bpp = 8;      format->bigEndian = true;      format->trueColor = true;      format->redMax = 7;      format->greenMax = 7;      format->blueMax = 3;      format->redShift = 0;      format->greenShift = 3;      format->blueShift = 6;    } else if (chosenDepth == 16) {      format->bpp = 16;      format->bigEndian = (*(char *)&endianTest) ? FALSE : TRUE;      format->trueColor = true;      format->redMax = 31;      format->greenMax = 63;      format->blueMax = 31;      format->redShift = 11;      format->greenShift = 5;      format->blueShift = 0;    }  }  format->redMax = Swap16IfLE( format->redMax );  format->greenMax = Swap16IfLE( format->greenMax );  format->blueMax = Swap16IfLE( format->blueMax );}void KRFBDecoder::sendPixelFormat(){  static char padding[3];  con->write( &SetPixelFormatId, 1 );  con->write( padding, 3 );  con->write( &(format->bpp), 1 );  con->write( &(format->depth), 1 );  con->write( &(format->bigEndian), 1 );  con->write( &(format->trueColor), 1 );  con->write( &(format->redMax), 2 );  con->write( &(format->greenMax), 2 );  con->write( &(format->blueMax), 2 );  con->write( &(format->redShift), 1 );  con->write( &(format->greenShift), 1 );  con->write( &(format->blueShift), 1 );  con->write( format->padding, 3 ); // Padding}void KRFBDecoder::sendAllowedEncodings(){  qDebug( "Sending encodings" );  static CARD8 padding[1];  con->write( &SetEncodingsId, 1 );  con->write( padding, 1 );  CARD16 noEncodings = con->options()->encodings();  noEncodings = Swap16IfLE( noEncodings );  con->write( &noEncodings, 2 );  if ( con->options()->corre )    con->write( &CorreEncoding, 4 );  if ( con->options()->hexTile )    con->write( &HexTileEncoding, 4 );  if ( con->options()->rre )    con->write( &RreEncoding, 4 );  if ( con->options()->copyrect )    con->write( &CopyRectEncoding, 4 );  // We always support this  con->write( &RawEncoding, 4 );}void KRFBDecoder::sendUpdateRequest( bool incremental ){  if ( currentState != Idle )    return;  con->write( &UpdateRequestId, 1 );  con->write( &incremental, 1 );  static CARD16 x = 0, y = 0;  static CARD16 w = Swap16IfLE( info->width );  static CARD16 h = Swap16IfLE( info->height );  con->write( &x, 2 );  con->write( &y, 2 );  con->write( &w, 2 );  con->write( &h, 2 );  // Now wait for the update  currentState = AwaitingUpdate;  connect( con, SIGNAL( gotEnoughData() ), SLOT( gotUpdateHeader() ) );  con->waitForData( UpdateHeaderLength );}void KRFBDecoder::gotUpdateHeader(){  assert( currentState == AwaitingUpdate );  //  qWarning( "Got update header" );  disconnect( con, SIGNAL( gotEnoughData() ), 	      this, SLOT( gotUpdateHeader() ) );  CARD8 msgType;  con->read( &msgType, 1 );  if ( msgType != UpdateId ) {    // We might have a bell or server cut    if ( msgType == ServerCutId ) {      oldState = currentState;      gotServerCut();    }    else if ( msgType == BellId ) {      oldState = currentState;      gotBell();    }    else {      int msg = msgType;      QString protocolError = tr( "Protocol Error: Message Id %1 was "                                    "found when expecting an update "                                    "message." ).arg( msg );      currentState = Error;      emit error( protocolError );    }    return;      }  CARD8 padding;  con->read( &padding, 1 );  con->read( &noRects, 2 );  noRects = Swap16IfLE( noRects );//  qWarning( "Expecting %d rects", noRects );  // Now wait for the data  currentState = AwaitingRectHeader;  connect( con, SIGNAL( gotEnoughData() ), SLOT( gotRectHeader() ) );  con->waitForData( RectHeaderLength );}void KRFBDecoder::gotRectHeader(){  assert( currentState == AwaitingRectHeader );  //  qWarning( "Got rect header" );  disconnect( con, SIGNAL( gotEnoughData() ), 	      this, SLOT( gotRectHeader() ) );  con->read( &x, 2 );  x = Swap16IfLE( x );  con->read( &y, 2 );  y = Swap16IfLE( y );  con->read( &w, 2 );  w = Swap16IfLE( w );  con->read( &h, 2 );  h = Swap16IfLE( h );  con->read( &encoding, 4 );//  CARD32 encodingLocal = Swap32IfLE( encoding );//  qWarning( "Rect: x=%d, y= %d, w=%d, h=%d, encoding=%ld", //  	   x, y, w, h, encodingLocal );  if ( !w || !h )    return;  //  // Each encoding needs to be handled differently. Some require  // waiting for more data, but others like a copyrect do not.  // Our constants have already been byte swapped, so we use  // the remote value as is.  //  if ( encoding == RawEncoding ) {    handleRawRect();  }  else if ( encoding == CopyRectEncoding ) {    handleCopyRect();  }  else if ( encoding == RreEncoding ) {    rreRects = 0;    rreMode = RRE;    currentState = AwaitingRRECount;    connect( con, SIGNAL(gotEnoughData()), SLOT(handleRRERect()) );    con->waitForData( 4+format->bpp/8 );  }  else if ( encoding == CorreEncoding ) {    rreRects = 0;    rreMode = CoRRE;    currentState = AwaitingRRECount;    connect( con, SIGNAL(gotEnoughData()), SLOT(handleRRERect()) );    con->waitForData( 4+format->bpp/8 );  }  else if ( encoding == HexTileEncoding ) {    currentState = AwaitingHexEncoding;    subX = 0;    subY = 0;    connect( con, SIGNAL(gotEnoughData()), SLOT(handleHexTileRect()) );    con->waitForData( 1 );  }  else {    int msg = Swap32IfLE( encoding );    QString protocolError = tr( "Protocol Error: An unknown encoding was "				  "used by the server %1" ).arg( msg );    currentState = Error;    qWarning( "Unknown encoding, %d", msg );    emit error( protocolError );

⌨️ 快捷键说明

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