| /** |
| * @example backchannel-client.c |
| * A simple example of an RFB client |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <time.h> |
| #include <errno.h> |
| #include <rfb/rfbclient.h> |
| |
| static void HandleRect(rfbClient* client, int x, int y, int w, int h) { |
| } |
| |
| /* |
| * The client part of the back channel extension example. |
| * |
| */ |
| |
| #define rfbBackChannel 155 |
| |
| typedef struct backChannelMsg { |
| uint8_t type; |
| uint8_t pad1; |
| uint16_t pad2; |
| uint32_t size; |
| } backChannelMsg; |
| |
| static void sendMessage(rfbClient* client, char* text) |
| { |
| backChannelMsg msg; |
| uint32_t length = strlen(text)+1; |
| |
| msg.type = rfbBackChannel; |
| msg.size = rfbClientSwap32IfLE(length); |
| if(!WriteToRFBServer(client, (char*)&msg, sizeof(msg)) || |
| !WriteToRFBServer(client, text, length)) { |
| rfbClientLog("enableBackChannel: write error (%d: %s)", errno, strerror(errno)); |
| } |
| } |
| |
| static rfbBool handleBackChannelMessage(rfbClient* client, |
| rfbServerToClientMsg* message) |
| { |
| backChannelMsg msg; |
| char* text; |
| |
| if(message->type != rfbBackChannel) |
| return FALSE; |
| |
| rfbClientSetClientData(client, sendMessage, sendMessage); |
| |
| if(!ReadFromRFBServer(client, ((char*)&msg)+1, sizeof(msg)-1)) |
| return TRUE; |
| msg.size = rfbClientSwap32IfLE(msg.size); |
| text = malloc(msg.size); |
| if(!ReadFromRFBServer(client, text, msg.size)) { |
| free(text); |
| return TRUE; |
| } |
| |
| rfbClientLog("got back channel message: %s\n", text); |
| free(text); |
| |
| return TRUE; |
| } |
| |
| static int backChannelEncodings[] = { rfbBackChannel, 0 }; |
| |
| static rfbClientProtocolExtension backChannel = { |
| backChannelEncodings, /* encodings */ |
| NULL, /* handleEncoding */ |
| handleBackChannelMessage, /* handleMessage */ |
| NULL /* next extension */ |
| }; |
| |
| int |
| main(int argc, char **argv) |
| { |
| rfbClient* client = rfbGetClient(8,3,4); |
| |
| client->GotFrameBufferUpdate = HandleRect; |
| rfbClientRegisterExtension(&backChannel); |
| |
| if (!rfbInitClient(client,&argc,argv)) |
| return 1; |
| |
| while (1) { |
| /* After each idle second, send a message */ |
| if(WaitForMessage(client,1000000)>0) |
| HandleRFBServerMessage(client); |
| else if(rfbClientGetClientData(client, sendMessage)) |
| sendMessage(client, "Dear Server,\n" |
| "thank you for understanding " |
| "back channel messages!"); |
| } |
| |
| rfbClientCleanup(client); |
| |
| return 0; |
| } |
| |