1 /** 2 * @example backchannel-client.c 3 * A simple example of an RFB client 4 */ 5 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <time.h> 9 #include <errno.h> 10 #include <rfb/rfbclient.h> 11 12 static void HandleRect(rfbClient* client, int x, int y, int w, int h) { 13 } 14 15 /* 16 * The client part of the back channel extension example. 17 * 18 */ 19 20 #define rfbBackChannel 155 21 22 typedef struct backChannelMsg { 23 uint8_t type; 24 uint8_t pad1; 25 uint16_t pad2; 26 uint32_t size; 27 } backChannelMsg; 28 29 static void sendMessage(rfbClient* client, char* text) 30 { 31 backChannelMsg msg; 32 uint32_t length = strlen(text)+1; 33 34 msg.type = rfbBackChannel; 35 msg.size = rfbClientSwap32IfLE(length); 36 if(!WriteToRFBServer(client, (char*)&msg, sizeof(msg)) || 37 !WriteToRFBServer(client, text, length)) { 38 rfbClientLog("enableBackChannel: write error (%d: %s)", errno, strerror(errno)); 39 } 40 } 41 42 static rfbBool handleBackChannelMessage(rfbClient* client, 43 rfbServerToClientMsg* message) 44 { 45 backChannelMsg msg; 46 char* text; 47 48 if(message->type != rfbBackChannel) 49 return FALSE; 50 51 rfbClientSetClientData(client, sendMessage, sendMessage); 52 53 if(!ReadFromRFBServer(client, ((char*)&msg)+1, sizeof(msg)-1)) 54 return TRUE; 55 msg.size = rfbClientSwap32IfLE(msg.size); 56 text = malloc(msg.size); 57 if(!ReadFromRFBServer(client, text, msg.size)) { 58 free(text); 59 return TRUE; 60 } 61 62 rfbClientLog("got back channel message: %s\n", text); 63 free(text); 64 65 return TRUE; 66 } 67 68 static int backChannelEncodings[] = { rfbBackChannel, 0 }; 69 70 static rfbClientProtocolExtension backChannel = { 71 backChannelEncodings, /* encodings */ 72 NULL, /* handleEncoding */ 73 handleBackChannelMessage, /* handleMessage */ 74 NULL /* next extension */ 75 }; 76 77 int 78 main(int argc, char **argv) 79 { 80 rfbClient* client = rfbGetClient(8,3,4); 81 82 client->GotFrameBufferUpdate = HandleRect; 83 rfbClientRegisterExtension(&backChannel); 84 85 if (!rfbInitClient(client,&argc,argv)) 86 return 1; 87 88 while (1) { 89 /* After each idle second, send a message */ 90 if(WaitForMessage(client,1000000)>0) 91 HandleRFBServerMessage(client); 92 else if(rfbClientGetClientData(client, sendMessage)) 93 sendMessage(client, "Dear Server,\n" 94 "thank you for understanding " 95 "back channel messages!"); 96 } 97 98 rfbClientCleanup(client); 99 100 return 0; 101 } 102 103