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
HandleRect(rfbClient * client,int x,int y,int w,int h)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
sendMessage(rfbClient * client,char * text)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
handleBackChannelMessage(rfbClient * client,rfbServerToClientMsg * message)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
main(int argc,char ** argv)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