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
12static 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
22typedef struct backChannelMsg {
23        uint8_t type;
24        uint8_t pad1;
25        uint16_t pad2;
26        uint32_t size;
27} backChannelMsg;
28
29static 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
42static 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
68static int backChannelEncodings[] = { rfbBackChannel, 0 };
69
70static rfbClientProtocolExtension backChannel = {
71	backChannelEncodings,		/* encodings */
72	NULL,				/* handleEncoding */
73	handleBackChannelMessage,	/* handleMessage */
74	NULL				/* next extension */
75};
76
77int
78main(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