4 * This is a simple example demonstrating a protocol extension.
6 * The "back channel" permits sending commands between client and server.
7 * It works by sending plain text messages.
9 * As suggested in the RFB protocol, the back channel is enabled by asking
10 * for a "pseudo encoding", and enabling the back channel on the client side
11 * as soon as it gets a back channel message from the server.
13 * This implements the server part.
15 * Note: If you design your own extension and want it to be useful for others,
16 * too, you should make sure that
18 * - your server as well as your client can speak to other clients and
19 * servers respectively (i.e. they are nice if they are talking to a
20 * program which does not know about your extension).
22 * - if the machine is little endian, all 16-bit and 32-bit integers are
23 * swapped before they are sent and after they are received.
27 #define rfbBackChannel 155
29 typedef struct backChannelMsg {
36 rfbBool enableBackChannel(rfbClientPtr cl, void** data, int encoding)
38 if(encoding == rfbBackChannel) {
40 const char* text="Server acknowledges back channel encoding\n";
41 uint32_t length = strlen(text)+1;
44 rfbLog("Enabling the back channel\n");
46 msg.type = rfbBackChannel;
47 msg.size = Swap32IfLE(length);
48 if((n = rfbWriteExact(cl, (char*)&msg, sizeof(msg))) <= 0 ||
49 (n = rfbWriteExact(cl, text, length)) <= 0) {
50 rfbLogPerror("enableBackChannel: write");
57 static rfbBool handleBackChannelMessage(rfbClientPtr cl, void* data,
58 const rfbClientToServerMsg* message)
60 if(message->type == rfbBackChannel) {
64 if((n = rfbReadExact(cl, ((char*)&msg)+1, sizeof(backChannelMsg)-1)) <= 0) {
66 rfbLogPerror("handleBackChannelMessage: read");
70 msg.size = Swap32IfLE(msg.size);
71 if((text = malloc(msg.size)) == NULL) {
72 rfbErr("Could not allocate %d bytes\n", msg.size);
75 if((n = rfbReadExact(cl, text, msg.size)) <= 0) {
77 rfbLogPerror("handleBackChannelMessage: read");
81 rfbLog("got message:\n%s\n", text);
88 static int backChannelEncodings[] = {rfbBackChannel, 0};
90 static rfbProtocolExtension backChannelExtension = {
93 backChannelEncodings, /* pseudoEncodings */
94 enableBackChannel, /* enablePseudoEncoding */
95 handleBackChannelMessage, /* handleMessage */
98 NULL, /* processArgument */
99 NULL /* next extension */
102 int main(int argc,char** argv)
104 rfbScreenInfoPtr server;
106 rfbRegisterProtocolExtension(&backChannelExtension);
108 server=rfbGetScreen(&argc,argv,400,300,8,3,4);
109 server->frameBuffer=(char*)malloc(400*300*4);
110 rfbInitServer(server);
111 rfbRunEventLoop(server,-1,FALSE);