10.01.2014 Views

The RFB Protocol

The RFB Protocol

The RFB Protocol

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>The</strong> <strong>RFB</strong> <strong>Protocol</strong><br />

Tristan Richardson<br />

Kenneth R. Wood<br />

ORL<br />

Cambridge<br />

Version 3.3<br />

January 1998<br />

Revised 16 July 1998<br />

1 Introduction<br />

<strong>RFB</strong> (“remote framebuffer”) is a simple protocol for remote access to graphical user<br />

interfaces. Because it works at the framebuffer level it is applicable to all windowing<br />

systems and applications, including X11, Windows 3.1/95/NT and Macintosh.<br />

<strong>The</strong> remote endpoint where the user sits (i.e. the display plus keyboard and/or pointer) is<br />

called the <strong>RFB</strong> client. <strong>The</strong> endpoint where changes to the framebuffer originate (i.e. the<br />

windowing system and applications) is known as the <strong>RFB</strong> server.<br />

<strong>RFB</strong> Server<br />

<strong>RFB</strong> Client<br />

<strong>RFB</strong><br />

<strong>Protocol</strong><br />

<strong>RFB</strong> is truly a “thin client” protocol. <strong>The</strong> emphasis in the design of the <strong>RFB</strong> protocol is<br />

to make very few requirements of the client. In this way, clients can run on the widest<br />

range of hardware, and the task of implementing a client is made as simple as possible.<br />

1


2 DISPLAY PROTOCOL 2<br />

<strong>The</strong> protocol also makes the client stateless. If a client disconnects from a given server<br />

and subsequently reconnects to that same server, the state of the user interface is preserved.<br />

Furthermore, a different client endpoint can be used to connect to the same <strong>RFB</strong><br />

server. At the new endpoint, the user will see exactly the same graphical user interface<br />

as at the original endpoint. In effect, the interface to the user’s applications becomes<br />

completely mobile. Wherever suitable network connectivity exists, the user can access<br />

their own personal applications, and the state of these applications is preserved between<br />

accesses from different locations. This provides the user with a familiar, uniform view<br />

of the computing infrastructure wherever they go.<br />

2 Display <strong>Protocol</strong><br />

<strong>The</strong> display side of the protocol is based around a single graphics primitive: “put a rectangle<br />

of pixel data at a given x,y position”. At first glance this might seem an inefficient<br />

way of drawing many user interface components. However, allowing various different<br />

encodings for the pixel data gives us a large degree of flexibility in how to trade off various<br />

parameters such as network bandwidth, client drawing speed and server processing<br />

speed.<br />

A sequence of these rectangles makes a framebuffer update (or simply update). An<br />

update represents a change from one valid framebuffer state to another, so in some ways<br />

is similar to a frame of video. <strong>The</strong> rectangles in an update are usually disjoint but this<br />

is not necessarily the case.<br />

<strong>The</strong> update protocol is demand-driven by the client. That is, an update is only sent from<br />

the server to the client in response to an explicit request from the client. This gives the<br />

protocol an adaptive quality. <strong>The</strong> slower the client and the network are, the lower the<br />

rate of updates becomes. With typical applications, changes to the same area of the<br />

framebuffer tend to happen soon after one another. With a slow client and/or network,<br />

transient states of the framebuffer can be ignored, resulting in less network traffic and<br />

less drawing for the client.<br />

3 Input <strong>Protocol</strong><br />

<strong>The</strong> input side of the protocol is based on a standard workstation model of a keyboard<br />

and multi-button pointing device. Input events are simply sent to the server by the client<br />

whenever the user presses a key or pointer button, or whenever the pointing device is<br />

moved. <strong>The</strong>se input events can also be synthesised from other non-standard I/O devices.<br />

For example, a pen-based handwriting recognition engine might generate keyboard<br />

events.<br />

4 Representation of pixel data<br />

Initial interaction between the <strong>RFB</strong> client and server involves a negotiation of the format<br />

and encoding with which pixel data will be sent. This negotiation has been de-


4 REPRESENTATION OF PIXEL DATA 3<br />

signed to make the job of the client as easy as possible. <strong>The</strong> bottom line is that the<br />

server must always be able to supply pixel data in the form the client wants. However<br />

if the client is able to cope equally with several different formats or encodings, it may<br />

choose one which is easier for the server to produce.<br />

Pixel format refers to the representation of individual colours by pixel values. <strong>The</strong> most<br />

common pixel formats are 24-bit or 16-bit “true colour”, where bit-fields within the<br />

pixel value translate directly to red, green and blue intensities, and 8-bit “colour map”<br />

where an arbitrary mapping can be used to translate from pixel values to the RGB intensities.<br />

Encoding refers to how a rectangle of pixel data will be sent on the wire. Every rectangle<br />

of pixel data is prefixed by a header giving the X,Y position of the rectangle on the<br />

screen, the width and height of the rectangle, and an encoding type which specifies the<br />

encoding of the pixel data. <strong>The</strong> data itself then follows using the specified encoding.<br />

<strong>The</strong> protocol can be extended by adding new encoding types. <strong>The</strong> encoding types defined<br />

at present are raw encoding, copy rectangle encoding, RRE (rise-and-run-length)<br />

encoding, CoRRE (Compact RRE) encoding and hextile encoding. In practice we normally<br />

use only the hextile and copy rectangle encodings since they provide the best<br />

compression for typical desktops. Other examples of possible encodings include JPEG<br />

for still images and MPEG for efficient transmission of moving images.<br />

4.1 Raw encoding<br />

<strong>The</strong> simplest encoding type is raw pixel data. In this case the data consists of n pixel<br />

values where n is the width times the height of the rectangle. <strong>The</strong> values simply represent<br />

each pixel in left-to-right scanline order. All <strong>RFB</strong> clients must be able to cope<br />

with pixel data in this raw encoding, and <strong>RFB</strong> servers should only produce raw encoding<br />

unless the client specifically asks for some other encoding type.<br />

4.2 Copy Rectangle encoding<br />

<strong>The</strong> copy rectangle encoding is a very simple and efficient encoding which can be used<br />

when the client already has the same pixel data elsewhere in its framebuffer. <strong>The</strong> encoding<br />

on the wire simply consists of an X,Y coordinate. This gives a position in the<br />

framebuffer from which the client can copy the rectangle of pixel data. This can be used<br />

in a variety of situations, the most obvious of which are when the user moves a window<br />

across the screen, and when the contents of a window are scrolled. A less obvious use<br />

is for optimising drawing of text or other repeating patterns. An intelligent server may<br />

be able to send a pattern explicitly only once, and knowing the previous position of the<br />

pattern in the framebuffer, send subsequent occurrences of the same pattern using the<br />

copy rectangle encoding.


4 REPRESENTATION OF PIXEL DATA 4<br />

4.3 RRE encoding<br />

RRE stands for rise-and-run-length encoding and as its name implies, it is essentially<br />

a two-dimensional analogue of run-length encoding. RRE-encoded rectangles are not<br />

only compressed to the same degree or better than is possible with run-length encoding<br />

but, more importantly, they arrive at the client in a form which can be rendered immediately<br />

and efficiently by the simplest of graphics engines. Thus, RRE is aimed at<br />

situations where compression is desired but the <strong>RFB</strong> client is insufficiently powerful to<br />

perform any decompression fast enough to maintain interactive performance.<br />

<strong>The</strong> basic idea behind RRE is the partitioning of a rectangle of pixel data into rectangular<br />

subregions (subrectangles) each of which consists of pixels of a single value and the<br />

union of which comprises the original rectangular region. <strong>The</strong> near-optimal partition<br />

of a given rectangle into such subrectangles is relatively easy to compute.<br />

<strong>The</strong> resulting encoding on the wire consists of a background pixel value, V b (typically<br />

the most prevalent pixel value in the rectangle) and a count N, followed by a list of<br />

N subrectangles, each of which consists of a tuple < v; x; y; w; h > where v (6= V b )<br />

is the pixel value, (x; y) are the coordinates of the subrectangle relative to the top-left<br />

corner of the rectangle, and (w; h) are the width and height of the subrectangle. <strong>The</strong><br />

client can render the original rectangle by drawing a filled rectangle of the background<br />

pixel value and then drawing a filled rectangle corresponding to each subrectangle.<br />

4.4 CoRRE encoding<br />

CoRRE is a variant of RRE, where we guarantee that the largest rectangle sent is no<br />

more than 255x255 pixels. A server which wants to send a rectangle larger than this<br />

simply splits it up and sends several smaller <strong>RFB</strong> rectangles. Within each of these<br />

smaller rectangles, a single byte can then be used to represent the dimensions of the<br />

subrectangles. For a typical desktop, this results in better compression than RRE. In<br />

fact, the best compression is achieved when we limit the rectangle size even more -<br />

current implementations use a maximum of 48x48. This is because rectangles which<br />

do not encode well (typically those containing image data) are sent as raw, while the<br />

ones which do encode well are sent as CoRRE. <strong>The</strong> smaller the maximum rectangle<br />

size, the finer the granularity of this decision. With RRE, the whole original rectangle<br />

must either be sent as RRE, or the whole thing sent as raw. However, since there is a<br />

certain overhead incurred by each <strong>RFB</strong> rectangle, making the maximum rectangle size<br />

too small (and thus increasing the number of <strong>RFB</strong> rectangles), results in worse compression.<br />

4.5 Hextile encoding<br />

Hextile is a variation on the CoRRE idea. Rectangles are split up into 16x16 tiles, allowing<br />

the dimensions of the subrectangles to be specified in 4 bits each, 16 bits in total.<br />

Unlike CoRRE, tiles are not top-level <strong>RFB</strong> rectangles. When splitting the original rectangle<br />

into tiles this is done in a predetermined way. This means that the position and<br />

size of each tile do not have to be explicitly specified - the encoded contents of the tiles


5 PROTOCOL MESSAGES 5<br />

simply follow one another in the predetermined order. <strong>The</strong> ordering of tiles that we use<br />

is starting at the top left going in left-to-right, top-to-bottom order. If the width of the<br />

whole rectangle is not an exact multiple of 16 then the width of the last tile in each row<br />

will be correspondingly smaller. Similarly if the height of the whole rectangle is not an<br />

exact multiple of 16 then the height of each tile in the final row will also be smaller.<br />

Each tile is either encoded as raw pixel data, or as a variation on RRE - this is specified<br />

by a type byte for each tile. Each tile has a background pixel value, as before. However,<br />

the background pixel value does not need to be explicitly specified for a given tile if it<br />

is the same as the background of the previous tile. If all of the subrectangles of a tile<br />

have the same pixel value, this can be specified once as a foreground pixel value for the<br />

whole tile. As with the background, the foreground pixel value can be left unspecified,<br />

meaning it is carried over from the previous tile.<br />

5 <strong>Protocol</strong> Messages<br />

<strong>The</strong> <strong>RFB</strong> protocol can operate over any reliable transport, either byte-stream or messagebased.<br />

<strong>The</strong>re are two stages to the protocol; an initial handshaking phase followed by<br />

the normal protocol interaction.<br />

<strong>The</strong> initial handshaking consists of <strong>Protocol</strong>Version, Authentication, ClientInitialisation<br />

and ServerInitialisation messages, as described below. Note that both client and<br />

server send a <strong>Protocol</strong>Version message.<br />

<strong>The</strong> protocol proceeds to the normal interaction stage after the ServerInitialisation message.<br />

At this stage, the client can send whichever messages it wants, and may receive<br />

messages from the server as a result. All these messages begin with a message-type<br />

byte, followed by any message-specific data.<br />

<strong>The</strong> following descriptions of protocol messages use the basic types CARD8, CARD16,<br />

CARD32, INT8, INT16, INT32. <strong>The</strong>se represent respectively 8, 16 and 32-bit unsigned<br />

integers and 8, 16 and 32-bit signed integers. All multiple byte integers (other<br />

than pixel values themselves) are in big endian order (most significant byte first).


5 PROTOCOL MESSAGES 6<br />

5.1 Initial Handshaking Messages


5.1 INITIAL HANDSHAKING MESSAGES 7<br />

5.1.1 <strong>Protocol</strong>Version<br />

Handshaking begins by the server sending the client a <strong>Protocol</strong>Version message. This<br />

lets the client know which is the latest <strong>RFB</strong> protocol version number supported by the<br />

server. <strong>The</strong> client then replies with a similar message giving the version number of the<br />

protocol which should actually be used (which may be different to that quoted by the<br />

server).<br />

It is intended that both clients and servers may provide some level of backwards compatibility<br />

by this mechanism. Servers in particular should attempt to provide backwards<br />

compatibility, and even forwards compatibility to some extent. For example if a client<br />

demands version 3.1 of the protocol, a 3.0 server can probably assume that by ignoring<br />

requests for encoding types it doesn’t understand, everything will still work OK. This<br />

will probably not be the case for changes in the major version number.<br />

<strong>The</strong> <strong>Protocol</strong>Version message consists of 12 bytes interpreted as a string of ASCII characters<br />

in the format "<strong>RFB</strong> xxx.yyy\n" where xxx and yyy are the major and minor<br />

version numbers, padded with zeros.<br />

No. of bytes Value<br />

12 "<strong>RFB</strong> 003.003\n" (hex 52 46 42 20 30 30 33 2e 30 30 33 0a)


5.1 INITIAL HANDSHAKING MESSAGES 8<br />

5.1.2 Authentication<br />

Once the protocol version has been decided, the server then sends a word indicating the<br />

authentication scheme to be used on the connection:<br />

No. of bytes Type [Value] Description<br />

4 CARD32 authentication-scheme:<br />

0 connection failed<br />

1 no authentication<br />

2 VNC authentication<br />

This is followed by data specific to the authentication-scheme:<br />

connection failed - for some reason the connection failed (e.g. the server cannot<br />

support the desired protocol version). This is followed by a string describing<br />

the reason (where a string is specified as a length followed by that many ASCII<br />

characters):<br />

No. of bytes Type [Value] Description<br />

4 CARD32 reason-length<br />

reason-length CARD8 array reason-string<br />

<strong>The</strong> server closes the connection after sending the reason-string.<br />

no authentication - no authentication is needed. <strong>The</strong> protocol continues with the<br />

ClientInitialisation message.<br />

VNC authentication - VNC authentication is to be used. This is followed by a<br />

random 16-byte challenge:<br />

No. of bytes Type [Value] Description<br />

16 CARD8 challenge<br />

<strong>The</strong> client encrypts the challenge with DES, using a password supplied by the<br />

user as the key, and sends the resulting 16-byte response:<br />

No. of bytes Type [Value] Description<br />

16 CARD8 response<br />

<strong>The</strong> server sends a word to inform the client whether authentication was successful.<br />

If so, the protocol continues with the ClientInitialisation message; if not the<br />

server closes the connection:<br />

No. of bytes Type [Value] Description<br />

4 CARD32 status:<br />

0 OK<br />

1 failed<br />

2 too-many<br />

If the server decides that too-many authentication failures have occurred, it should<br />

not allow immediate reconnection by the same client.


5.1 INITIAL HANDSHAKING MESSAGES 9<br />

5.1.3 ClientInitialisation<br />

Once the client and server are sure that they’re happy to talk to one another, the client<br />

sends an initialisation message:<br />

No. of bytes Type [Value] Description<br />

1 CARD8 shared-flag<br />

Shared-flag is non-zero (true) if the server should try to share the desktop by leaving<br />

other clients connected, zero (false) if it should give exclusive access to this client by<br />

disconnecting all other clients.


5.1 INITIAL HANDSHAKING MESSAGES 10<br />

5.1.4 ServerInitialisation<br />

After receiving the ClientInitialisation message, the server sends a ServerInitialistion<br />

message. This tells the client the width and height of the server’s framebuffer, its pixel<br />

format and the name associated with the desktop:<br />

No. of bytes Type [Value] Description<br />

2 CARD16 framebuffer-width<br />

2 CARD16 framebuffer-height<br />

16 PIXEL_FORMAT server-pixel-format<br />

4 CARD32 name-length<br />

name-length CARD8 array name-string<br />

where PIXEL_FORMAT is<br />

No. of bytes Type [Value] Description<br />

1 CARD8 bits-per-pixel<br />

1 CARD8 depth<br />

1 CARD8 big-endian-flag<br />

1 CARD8 true-colour-flag<br />

2 CARD16 red-max<br />

2 CARD16 green-max<br />

2 CARD16 blue-max<br />

1 CARD8 red-shift<br />

1 CARD8 green-shift<br />

1 CARD8 blue-shift<br />

3 padding<br />

Server-pixel-format specifies the server’s natural pixel format. This pixel format will<br />

be used unless the client requests a different format using the SetPixelFormat message<br />

(section 5.2.1).<br />

Bits-per-pixel is the number of bits used for each pixel value on the wire. This must<br />

be greater than or equal to the depth which is the number of useful bits in the pixel<br />

value. Currently bits-per-pixel must be 8, 16 or 32 — less than 8-bit pixels are not yet<br />

supported. Big-endian-flag is non-zero (true) if multi-byte pixels are interpreted as big<br />

endian. Of course this is meaningless for 8 bits-per-pixel.<br />

If true-colour-flag is non-zero (true) then the last six items specify how to extract the<br />

red, green and blue intensities from the pixel value. Red-max is the maximum red value<br />

(= 2 n , 1 where n is the number of bits used for red). Note this value is always in big<br />

endian order. Red-shift is the number of shifts needed to get the red value in a pixel<br />

to the least significant bit. Green-max, green-shift and blue-max, blue-shift are similar<br />

for green and blue. For example, to find the red value (between 0 and red-max) from a<br />

given pixel, do the following:<br />

Swap the pixel value according to big-endian-flag (e.g. if big-endian-flag is zero<br />

(false) and host byte order is big endian, then swap).


5.1 INITIAL HANDSHAKING MESSAGES 11<br />

Shift right by red-shift.<br />

AND with red-max (in host byte order).<br />

Currently there is little or no support for colour maps. Some preliminary work was done<br />

on this, but is incomplete. It was intended to be something like this:<br />

If true-colour-flag is zero (false) then the server uses pixel values which are<br />

not directly composed from the red, green and blue intensities, but which<br />

serve as indices into a colour map. Entries in the colour map can be set either<br />

by the client using the FixColourMapEntries message (section 5.2.2)<br />

or by the server using the SetColourMapEntries message (section 5.3.2).<br />

<strong>The</strong> FixColourMapEntries message is not supported by any currently available servers,<br />

and colour maps are only supported at all by the X-based server. In fact, for proper<br />

colour map support the client probably needs to be able to specify particular pixel values<br />

which the server should not use. This may be added in future versions of the protocol,<br />

but don’t hold your breath.


5.1 INITIAL HANDSHAKING MESSAGES 12<br />

5.2 Client to server messages


5.2 CLIENT TO SERVER MESSAGES 13<br />

5.2.1 SetPixelFormat<br />

Sets the format in which pixel values should be sent in FramebufferUpdate messages.<br />

If the client does not send a SetPixelFormat message then the server sends pixel values<br />

in its natural format as specified in the ServerInitialisation message (section 5.1.4).<br />

Currently there is little or no support for colour maps. Some preliminary work was done<br />

on this, but is incomplete. It was intended to be something like this:<br />

If true-colour-flag is zero (false) then this indicates that a “colour map” is<br />

to be used. <strong>The</strong> client can fix any of the entries in the colour map using the<br />

FixColourMapEntries message (section 5.2.2). Any entries not fixed by<br />

the client may be set dynamically as desired by the server using the Set-<br />

ColourMapEntries message (section 5.3.2). Immediately after the client<br />

has sent this message the colour map is empty, even if entries had previously<br />

been fixed by the client or set by the server.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 0 message-type<br />

3 padding<br />

16 PIXEL_FORMAT pixel-format<br />

where PIXEL_FORMAT is as described in section 5.1.4:<br />

No. of bytes Type [Value] Description<br />

1 CARD8 bits-per-pixel<br />

1 CARD8 depth<br />

1 CARD8 big-endian-flag<br />

1 CARD8 true-colour-flag<br />

2 CARD16 red-max<br />

2 CARD16 green-max<br />

2 CARD16 blue-max<br />

1 CARD8 red-shift<br />

1 CARD8 green-shift<br />

1 CARD8 blue-shift<br />

3 padding


5.2 CLIENT TO SERVER MESSAGES 14<br />

5.2.2 FixColourMapEntries<br />

Currently there is little or no support for colour maps. Some preliminary work was done<br />

on this, but is incomplete. It was intended to be something like this:<br />

When the pixel format uses a “colour map”, this message tells the server<br />

that the specified pixel values are mapped to the given RGB intensities.<br />

This means that the server may not subsequently specify RGB intensities<br />

for these pixel values using SetColourMapEntries messages (section 5.3.2).<br />

If the client has a fixed colour map it can simply send a FixColourMapEntries<br />

message describing its entire colour map and the server will then translate<br />

all pixel values as appropriate for the client’s colour map. In this case<br />

the server cannot send any SetColourMapEntries messages.<br />

Note that despite the name, the client can, if it desires, send a FixColourMapEntries<br />

message at any time. This includes messages remapping the same<br />

pixel values to different RGB intensities. However, the only way the client<br />

can indicate that a pixel value is no longer fixed is by sending another Set-<br />

PixelFormat message, which clears the entire colour map.<br />

<strong>The</strong> FixColourMapEntries message is not supported by any currently available<br />

servers.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 1 message-type<br />

1 padding<br />

2 CARD16 first-colour<br />

2 CARD16 number-of-colours<br />

followed by number-of-colours repetitions of the following:<br />

No. of bytes Type [Value] Description<br />

2 CARD16 red<br />

2 CARD16 green<br />

2 CARD16 blue


5.2 CLIENT TO SERVER MESSAGES 15<br />

5.2.3 SetEncodings<br />

Sets the encoding types in which pixel data can be sent by the server. <strong>The</strong> order of the<br />

encoding types given in this message is a hint by the client as to its preference (the first<br />

encoding specified being most preferred). <strong>The</strong> server may or may not choose to make<br />

use of this hint. Pixel data may always be sent in raw encoding even if not specified<br />

explicitly here.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 2 message-type<br />

1 padding<br />

2 CARD16 number-of-encodings<br />

followed by number-of-encodings repetitions of the following:<br />

No. of bytes Type [Value] Description<br />

4 CARD32 encoding-type<br />

0 raw encoding<br />

1 copy rectangle encoding<br />

2 RRE encoding<br />

4 CoRRE encoding<br />

5 hextile encoding


5.2 CLIENT TO SERVER MESSAGES 16<br />

5.2.4 FramebufferUpdateRequest<br />

Notifies the server that the client is interested in the area of the framebuffer specified by<br />

x-position, y-position, width and height. <strong>The</strong> server usually responds to a Framebuffer-<br />

UpdateRequest by sending a FramebufferUpdate. Note however that a single FramebufferUpdate<br />

may be sent in reply to several FramebufferUpdateRequests.<br />

<strong>The</strong> server assumes that the client keeps a copy of all parts of the framebuffer in which<br />

it is interested. This means that normally the server only needs to send incremental<br />

updates to the client.<br />

However, if for some reason the client has lost the contents of a particular area which it<br />

needs, then the client sends a FramebufferUpdateRequest with incremental set to zero<br />

(false). This requests that the server send the entire contents of the specified area as<br />

soon as possible. <strong>The</strong> area will not be updated using the copy rectangle encoding.<br />

If the client has not lost any contents of the area in which it is interested, then it sends a<br />

FramebufferUpdateRequest with incremental set to non-zero (true). If and when there<br />

are changes to the specified area of the framebuffer, the server will send a Framebuffer-<br />

Update. Note that there may be an indefinite period between the FramebufferUpdateRequest<br />

and the FramebufferUpdate.<br />

In the case of a fast client, the client may want to regulate the rate at which it sends<br />

incremental FramebufferUpdateRequests to avoid hogging the network.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 3 message-type<br />

1 CARD8 incremental<br />

2 CARD16 x-position<br />

2 CARD16 y-position<br />

2 CARD16 width<br />

2 CARD16 height


5.2 CLIENT TO SERVER MESSAGES 17<br />

5.2.5 KeyEvent<br />

A key press or release. Down-flag is non-zero (true) if the key is now pressed, zero<br />

(false) if it is now released. <strong>The</strong> key itself is specified using the “keysym” values defined<br />

by the X Window System. For full details, see <strong>The</strong> Xlib Reference Manual, published<br />

by O’Reilly & Associates, or see the header file from any X<br />

Window System installation.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 4 message-type<br />

1 CARD8 down-flag<br />

2 padding<br />

4 CARD32 key<br />

For most ordinary keys, the “keysym” is the same as the corresponding ASCII value.<br />

Other common keys are:<br />

Key name<br />

BackSpace<br />

Tab<br />

Return or Enter<br />

Escape<br />

Insert<br />

Delete<br />

Home<br />

End<br />

Page Up<br />

Page Down<br />

Left<br />

Up<br />

Right<br />

Down<br />

Keysym value<br />

0xff08<br />

0xff09<br />

0xff0d<br />

0xff1b<br />

0xff63<br />

0xffff<br />

0xff50<br />

0xff57<br />

0xff55<br />

0xff56<br />

0xff51<br />

0xff52<br />

0xff53<br />

0xff54<br />

Key name Keysym value<br />

F1<br />

0xffbe<br />

F2<br />

0xffbf<br />

F3<br />

0xffc0<br />

F4<br />

0xffc1<br />

... ...<br />

F12<br />

0xffc9<br />

Shift (left) 0xffe1<br />

Shift (right) 0xffe2<br />

Control (left) 0xffe3<br />

Control (right) 0xffe4<br />

Meta (left) 0xffe7<br />

Meta (right) 0xffe8<br />

Alt (left) 0xffe9<br />

Alt (right) 0xffea


5.2 CLIENT TO SERVER MESSAGES 18<br />

5.2.6 PointerEvent<br />

Indicates either pointer movement or a pointer button press or release. <strong>The</strong> pointer is<br />

now at (x-position, y-position), and the current state of buttons 1 to 8 are represented<br />

by bits 0 to 7 of button-mask respectively, 0 meaning up, 1 meaning down (pressed).<br />

No. of bytes Type [Value] Description<br />

1 CARD8 5 message-type<br />

1 CARD8 button-mask<br />

2 CARD16 x-position<br />

2 CARD16 y-position


5.2 CLIENT TO SERVER MESSAGES 19<br />

5.2.7 ClientCutText<br />

<strong>The</strong> client has new ASCII text in its cut buffer. End of lines are represented by the<br />

linefeed / newline character (ASCII value 10) alone. No carriage-return (ASCII value<br />

13) is needed.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 6 message-type<br />

3 padding<br />

4 CARD32 length<br />

length CARD8 array text


5.2 CLIENT TO SERVER MESSAGES 20<br />

5.3 Server to client messages


5.3 SERVER TO CLIENT MESSAGES 21<br />

5.3.1 FramebufferUpdate<br />

A framebuffer update consists of a sequence of rectangles of pixel data which the client<br />

should put into its framebuffer. It is sent in response to a FramebufferUpdateRequest<br />

from the client. Note that there may be an indefinite period between the Framebuffer-<br />

UpdateRequest and the FramebufferUpdate.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 0 message-type<br />

1 padding<br />

2 CARD16 number-of-rectangles<br />

This is followed by number-of-rectangles rectangles of pixel data. Each rectangle consists<br />

of:<br />

No. of bytes Type [Value] Description<br />

2 CARD16 x-position<br />

2 CARD16 y-position<br />

2 CARD16 width<br />

2 CARD16 height<br />

4 CARD32 encoding-type:<br />

0 raw encoding<br />

1 copy rectangle encoding<br />

2 RRE encoding<br />

4 CoRRE encoding<br />

5 hextile encoding<br />

followed by the pixel data in the specified encoding.<br />

For raw encoding the data consists of width height pixel values. <strong>The</strong> values<br />

simply represent each pixel in left-to-right scanline order.<br />

For copy rectangle encoding the data consists of:<br />

No. of bytes Type [Value] Description<br />

2 CARD16 src-x-position<br />

2 CARD16 src-y-position<br />

For RRE encoding the data begins with the header:<br />

No. of bytes Type [Value] Description<br />

4 CARD32 number-of-subrectangles<br />

n CARD background-pixel-value<br />

where 8n is the number of bits-per-pixel as agreed by the client and server – either<br />

in the ServerInitialisation message (section 5.1.4) or a SetPixelFormat message<br />

(section 5.2.1). This is followed by number-of-subrectangles instances of<br />

the following structure:


5.3 SERVER TO CLIENT MESSAGES 22<br />

No. of bytes Type [Value] Description<br />

n CARD subrect-pixel-value<br />

2 CARD16 x-position<br />

2 CARD16 y-position<br />

2 CARD16 width<br />

2 CARD16 height<br />

For CoRRE encoding the data begins with the header:<br />

No. of bytes Type [Value] Description<br />

4 CARD32 number-of-subrectangles<br />

n CARD background-pixel-value<br />

where 8n is the number of bits-per-pixel as agreed by the client and server – either<br />

in the ServerInitialisation message (section 5.1.4) or a SetPixelFormat message<br />

(section 5.2.1). This is followed by number-of-subrectangles instances of<br />

the following structure:<br />

No. of bytes Type [Value] Description<br />

n CARD subrect-pixel-value<br />

1 CARD8 x-position<br />

1 CARD8 y-position<br />

1 CARD8 width<br />

1 CARD8 height<br />

For hextile encoding the rectangle is divided up into tiles of 16x16 pixels, starting<br />

at the top left going in left-to-right, top-to-bottom order. If the width of the<br />

rectangle is not an exact multiple of 16 then the width of the last tile in each row<br />

will be correspondingly smaller. Similarly if the height is not an exact multiple<br />

of 16 then the height of each tile in the final row will also be smaller.<br />

Each tile begins with a subencoding type byte, which is a mask made up of a<br />

number of bits:<br />

No. of bytes Type [Value] Description<br />

1 CARD8 subencoding-mask:<br />

1 Raw<br />

2 BackgroundSpecified<br />

4 ForegroundSpecified<br />

8 AnySubrects<br />

16 SubrectsColoured<br />

If the Raw bit is set then the other bits are irrelevant; widthheight pixel values<br />

follow (where width and height are the width and height of the tile). Otherwise<br />

the other bits in the mask are as follows:<br />

BackgroundSpecified - if set, a pixel value follows which specifies the background<br />

colour for this tile:


5.3 SERVER TO CLIENT MESSAGES 23<br />

No. of bytes Type [Value] Description<br />

n CARD background-pixel-value<br />

where 8n is the number of bits-per-pixel as agreed by the client and server –<br />

either in the ServerInitialisation message (section 5.1.4) or a SetPixelFormat<br />

message (section 5.2.1). <strong>The</strong> first non-raw tile in a rectangle must have<br />

this bit set. If this bit isn’t set then the background is the same as the last<br />

tile.<br />

ForegroundSpecified - if set, a pixel value follows which specifies the foreground<br />

colour to be used for all subrectangles in this tile:<br />

No. of bytes Type [Value] Description<br />

n CARD foreground-pixel-value<br />

If this bit is set then the SubrectsColoured bit must be zero.<br />

AnySubrects - if set, a single byte follows giving the number of subrectangles<br />

following:<br />

No. of bytes Type [Value] Description<br />

1 CARD8 number-of-subrectangles<br />

If not set, there are no subrectangles (i.e. the whole tile is just solid background<br />

colour).<br />

SubrectsColoured - if set then each subrectangle is preceded by a pixel value<br />

giving the colour of that subrectangle, so a subrectangle is:<br />

No. of bytes Type [Value] Description<br />

n CARD subrect-pixel-value<br />

1 CARD8 x-and-y-position<br />

1 CARD8 width-and-height<br />

If not set, all subrectangles are the same colour, the foreground colour; if<br />

the ForegroundSpecified bit wasn’t set then the foreground is the same as<br />

the last tile. A subrectangle is:<br />

No. of bytes Type [Value] Description<br />

1 CARD8 x-and-y-position<br />

1 CARD8 width-and-height<br />

<strong>The</strong> position and size of each subrectangle is specified in two bytes, x-and-yposition<br />

and width-and-height. <strong>The</strong> most-significant four bits of x-and-y-position<br />

specify the X position, the least-significant specify the Y position. <strong>The</strong> mostsignificant<br />

four bits of width-and-height specify the width minus one, the leastsignificant<br />

specify the height minus one.


5.3 SERVER TO CLIENT MESSAGES 24<br />

5.3.2 SetColourMapEntries<br />

Currently there is little or no support for colour maps. Some preliminary work was done<br />

on this, but is incomplete. It was intended to be something like this:<br />

When the pixel format uses a “colour map”, this message tells the client<br />

that the specified pixel values should be mapped to the given RGB intensities.<br />

<strong>The</strong> server may only specify pixel values for which the client has<br />

not already set the RGB intensities using FixColourMapEntries (section<br />

5.2.2).<br />

Currently, colour maps are only supported at all by the X-based server.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 1 message-type<br />

1 padding<br />

2 CARD16 first-colour<br />

2 CARD16 number-of-colours<br />

followed by number-of-colours repetitions of the following:<br />

No. of bytes Type [Value] Description<br />

2 CARD16 red<br />

2 CARD16 green<br />

2 CARD16 blue


5.3 SERVER TO CLIENT MESSAGES 25<br />

5.3.3 Bell<br />

Ring a bell on the client if it has one.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 2 message-type


5.3 SERVER TO CLIENT MESSAGES 26<br />

5.3.4 ServerCutText<br />

<strong>The</strong> server has new ASCII text in its cut buffer. End of lines are represented by the<br />

linefeed / newline character (ASCII value 10) alone. No carriage-return (ASCII value<br />

13) is needed.<br />

No. of bytes Type [Value] Description<br />

1 CARD8 3 message-type<br />

3 padding<br />

4 CARD32 length<br />

length CARD8 array text

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!