#ifndef KRFBPROTO_H
#define KRFBPROTO_H

#include <qobject.h>
#include <qstring.h>
#include <qsignal.h>
#include <ksock.h>

#include <unistd.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define MAXPWLEN 8
#define CHALLENGESIZE 16
#define EN0	0	/* MODE == encrypt */
#define DE1	1	/* MODE == decrypt */

#define BUFFER_SIZE (640*480)

/*****************************************************************************
 *
 * Message types
 *
 *****************************************************************************/

/* server -> client */

#define rfbFramebufferUpdate 0
#define rfbSetColourMapEntries 1
#define rfbBell 2
#define rfbServerCutText 3

/* client -> server */


#define rfbSetPixelFormat 0
#define rfbFixColourMapEntries 1	/* not currently supported */
#define rfbSetEncodings 2
#define rfbFramebufferUpdateRequest 3
#define rfbKeyEvent 4
#define rfbPointerEvent 5
#define rfbClientCutText 6

/*****************************************************************************
 *
 * Encoding types
 *
 *****************************************************************************/

#define rfbEncodingRaw 0
#define rfbEncodingCopyRect 1
#define rfbEncodingRRE 2
#define rfbEncodingCoRRE 4
#define rfbEncodingHextile 5


typedef unsigned short CARD16;
typedef unsigned char  CARD8;
typedef unsigned long CARD32;


typedef struct {
  CARD8 type;	
  CARD8 pad;
  CARD16 nRects;
  /* followed by nRects rectangles */
} rfbFramebufferUpdateMsg;

#define sz_rfbFramebufferUpdateMsg 4

/*-----------------------------------------------------------------------------
 * Union of all server->client messages.
 */




typedef struct {
    CARD16 x;
    CARD16 y;
    CARD16 w;
    CARD16 h;
} rfbRectangle;

typedef struct {
    rfbRectangle r;
    CARD32 encoding;	/* one of the encoding types rfbEncoding... */
} rfbFramebufferUpdateRectHeader;

#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4)


/*-----------------------------------------------------------------------------
 * Structure used to specify pixel format.
 */

typedef struct {

    CARD8 bitsPerPixel;		/* 8,16,32 only */

    CARD8 depth;		/* 8 to 32 */

    CARD8 bigEndian;		/* True if multi-byte pixels are interpreted
				   as big endian, or if single-bit-per-pixel
				   has most significant bit of the byte
				   corresponding to first (leftmost) pixel. Of
				   course this is meaningless for 8 bits/pix */

    CARD8 trueColour;		/* If false then we need a "colour map" to
				   convert pixels to RGB.  If true, xxxMax and
				   xxxShift specify bits used for red, green
				   and blue */

    /* the following fields are only meaningful if trueColour is true */

    CARD16 redMax;		/* maximum red value (= 2^n - 1 where n is the
				   number of bits used for red). Note this
				   value is always in big endian order. */

    CARD16 greenMax;		/* similar for green */

    CARD16 blueMax;		/* and blue */

    CARD8 redShift;		/* number of shifts needed to get the red
				   value in a pixel to the least significant
				   bit. To find the red value from a given
				   pixel, do the following:
				   1) Swap pixel value according to bigEndian
				      (e.g. if bigEndian is false and host byte
				      order is big endian, then swap).
				   2) Shift right by redShift.
				   3) AND with redMax (in host byte order).
				   4) You now have the red value between 0 and
				      redMax. */

    CARD8 greenShift;		/* similar for green */

    CARD8 blueShift;		/* and blue */

    CARD8 pad1;
    CARD16 pad2;

} rfbPixelFormat;


typedef struct {
    CARD16 framebufferWidth;
    CARD16 framebufferHeight;
    rfbPixelFormat format;	/* the server's preferred pixel format */
    CARD32 nameLength;
    /* followed by char name[nameLength] */
} rfbServerInitMsg;

#define sz_rfbPixelFormat 16
#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat)
#define sz_rfbRectangle 8

typedef struct {
    CARD8 type;			/* always rfbSetPixelFormat */
    CARD8 pad1;
    CARD16 pad2;
    rfbPixelFormat format;
} rfbSetPixelFormatMsg;

#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4)

/*-----------------------------------------------------------------------------
 * SetEncodings - tell the RFB server which encoding types we accept.  Put them
 * in order of preference, if we have any.  We may always receive raw
 * encoding, even if we don't specify it here.
 */

typedef struct {
    CARD8 type;			/* always rfbSetEncodings */
    CARD8 pad;
    CARD16 nEncodings;
    /* followed by nEncodings * CARD32 encoding types */
} rfbSetEncodingsMsg;


typedef struct {
    CARD8 type;			/* always rfbFramebufferUpdateRequest */
    CARD8 incremental;
    CARD16 x;
    CARD16 y;
    CARD16 w;
    CARD16 h;
} rfbFramebufferUpdateRequestMsg;

#define sz_rfbFramebufferUpdateRequestMsg 10

typedef struct {
    CARD8 type;			/* always rfbSetColourMapEntries */
    CARD8 pad;
    CARD16 firstColour;
    CARD16 nColours;

    /* Followed by nColours * 3 * CARD16
       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */

} rfbSetColourMapEntriesMsg;

#define sz_rfbSetColourMapEntriesMsg 6



/*-----------------------------------------------------------------------------
 * Bell - ring a bell on the client if it has one.
 */

typedef struct {
    CARD8 type;			/* always rfbBell */
} rfbBellMsg;

#define sz_rfbBellMsg 1



/*-----------------------------------------------------------------------------
 * ServerCutText - the server has new text in its cut buffer.
 */

typedef struct {
    CARD8 type;			/* always rfbServerCutText */
    CARD8 pad1;
    CARD16 pad2;
    CARD32 length;
    /* followed by char text[length] */
} rfbServerCutTextMsg;

#define sz_rfbServerCutTextMsg 8


typedef union {
    CARD8 type;
    rfbFramebufferUpdateMsg fu;
    rfbSetColourMapEntriesMsg scme;
    rfbBellMsg b;
    rfbServerCutTextMsg sct;
} rfbServerToClientMsg;

typedef struct {
    CARD8 type;			/* always rfbKeyEvent */
    CARD8 down;			/* true if down (press), false if up */
    CARD16 pad;
    CARD32 key;			/* key is specified as an X keysym */
} rfbKeyEventMsg;

#define sz_rfbKeyEventMsg 8

/*-----------------------------------------------------------------------------
 * PointerEvent - mouse/pen move and/or button press.
 */

typedef struct {
    CARD8 type;			/* always rfbPointerEvent */
    CARD8 buttonMask;		/* bits 0-7 are buttons 1-8, 0=up, 1=down */
    CARD16 x;
    CARD16 y;
} rfbPointerEventMsg;

#define rfbButton1Mask 1
#define rfbButton2Mask 2
#define rfbButton3Mask 4

#define sz_rfbPointerEventMsg 6

#define sz_rfbSetEncodingsMsg 4
#define MAX_ENCODINGS 10

#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))




class kRfbProto :  public QObject {
Q_OBJECT

public:
 kRfbProto(const char *host = 0, int port = 0);
 ~kRfbProto(); 

 enum conState { ConnFailed = 0, NoAuth = 1, VncAuth = 2};
 enum authState {VncAuthOK = 0, VncAuthFailed = 1, VncAuthTooMany = 2, 
		 VncAuthUnknown = 3};
 enum options {FramebufferUpdate = 0, SetColourMapEntries = 1, Bell = 2,
	       ServerCutText = 3};
 enum encoding {EncodingRaw = 0, EncodingCopyRect = 1, EncodingRRE = 2,
		EncodingCoRRE = 4, EncodingHextile = 5};

 /** Return client's version **/
 const char *versionMsg() { return "RFB 003.003\n"; }

 /** Returns server's version **/
 const char *serverVersion() { return _serverVersion;}

 /** Get the server specific information **/
 rfbServerInitMsg *getServerInformation() { return &si;}

 /** Return host on which server is running **/
 const char *hostName() { return host;}

 /** Return desktop name **/
 char *desktop() { return desktopName;}

 /** Port number the server is running at **/
 int portNumber() { return port;}

 /** transmit a password to host. It -will- be DES encrypted **/
 int transmitPassword(char *);

 /** Call this function explictly to connect to host (The constr. won't!) **/
 int connect();

 /** You fiddled with your mouse! ;-) **/
 bool writePointerEvent(CARD8, int,int);

 /** and now you played with your keybord ( bool {up|down} ) **/
 bool writeKeyEvent(CARD32 , bool);
 
 /** Closes connection to host **/
 void close();

 /** Read servers version message to avoid incompatiblity **/
 void readVersionMsg();

 /** Write our version message to avoid incompatiblity **/
 void writeVersionMsg();

 /** Read authentifcation scheme **/
 int readAuthScheme();

 bool writeClientInit();
 bool readServerInit();
 void readFramebufferUpdate();
 void readFramebufferUpdateRectHdr();
 const char *readServerCutText();
 bool writeFramebufferUpdateRequest(int x, int y, int w, int h,
				    bool incremental);

 bool writePixelFormat(rfbServerInitMsg *msg);

 void writeFixColourMapEntries(int firstColour, int nColours,
			       int red[], int green[], int blue[]);

 bool writeEncodings();


 /****************** Private slots ***********************/

 private slots:

  void setServerVersion(const char *ver) { _serverVersion = ver;}
  void PrintPixelFormat(rfbPixelFormat *format);
  bool SameMachine(int);
  bool getData(KSocket *);
  void writeClientCutText(const char *text);
  bool readExact(int sock,char * buf,int len);
  bool writeExact(int sock,char *buf, int len);

  // Encryption
  /*  int vncEncryptAndStorePasswd(char *passwd, char *fname);
  char *vncDecryptPasswdFromFile(char *fname);
  void vncRandomBytes(unsigned char *bytes);
  void vncEncryptBytes(unsigned char *bytes, char *passwd);  */

  
  /******************** Signals **************************/

 signals:

  void sendData(CARD8*,int,int,int,int);
  void bell();
  void finished();
  void fatal();

  /******************* Private ***************************/

 private:
  QString _serverVersion;
  QString host;
  char  *desktopName;
  int port;
  KSocket *sock;
  QByteArray os;
  bool inNormalProtocol;
  rfbServerInitMsg si;
  int serverMajor; 
  int serverMinor;
  bool firstTrans;
  CARD8 challenge[CHALLENGESIZE];
  rfbPixelFormat myFormat;
  char buffer[BUFFER_SIZE];

  int HextileRaw;
  int HextileBackgroundSpecified;
  int HextileForegroundSpecified;
  int HextileAnySubrects;
  int HextileSubrectsColoured;
  
  int updateNRects;
  bool shareDesktop;

};
#endif





Documentation generated by rich@pegasus on Sun Mar 22 20:56:11 MET 1998