blob: dcb984a4ee09454cdc97c295944232a58007d4fc [file] [log] [blame]
Eddie James21b177e2018-12-11 13:14:46 -06001#pragma once
2
3#include "ikvm_args.hpp"
4#include "ikvm_input.hpp"
5#include "ikvm_video.hpp"
6
Eddie James29f775a2018-12-11 13:22:54 -06007#include <rfb/rfb.h>
8
9#include <vector>
10
Eddie James21b177e2018-12-11 13:14:46 -060011namespace ikvm
12{
13
14/*
15 * @class Server
16 * @brief Manages the RFB server connection and updates
17 */
18class Server
19{
20 public:
21 /*
22 * @struct ClientData
23 * @brief Store necessary data for each connected RFB client
24 */
25 struct ClientData
26 {
27 /*
28 * @brief Constructs ClientData object
29 *
30 * @param[in] s - Number of frames to skip when client connects
31 * @param[in] i - Pointer to Input object
32 */
Paul Fertser2d2f3da2021-06-18 11:16:43 +000033 ClientData(int s, Input* i) : skipFrame(s), input(i), last_crc{-1}
Eddie James21b177e2018-12-11 13:14:46 -060034 {
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070035 needUpdate = false;
Eddie James21b177e2018-12-11 13:14:46 -060036 }
37 ~ClientData() = default;
38 ClientData(const ClientData&) = default;
39 ClientData& operator=(const ClientData&) = default;
40 ClientData(ClientData&&) = default;
41 ClientData& operator=(ClientData&&) = default;
42
43 int skipFrame;
44 Input* input;
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070045 bool needUpdate;
Paul Fertser2d2f3da2021-06-18 11:16:43 +000046 int64_t last_crc;
Eddie James21b177e2018-12-11 13:14:46 -060047 };
48
49 /*
50 * @brief Constructs Server object
51 *
52 * @param[in] args - Reference to Args object
53 * @param[in] i - Reference to Input object
54 * @param[in] v - Reference to Video object
55 */
56 Server(const Args& args, Input& i, Video& v);
57 ~Server();
58 Server(const Server&) = default;
59 Server& operator=(const Server&) = default;
60 Server(Server&&) = default;
61 Server& operator=(Server&&) = default;
62
Eddie James29f775a2018-12-11 13:22:54 -060063 /* @brief Resizes the RFB framebuffer */
64 void resize();
65 /* @brief Executes any pending RFB updates and client input */
66 void run();
67 /* @brief Sends pending video frame to clients */
68 void sendFrame();
69
70 /*
71 * @brief Indicates whether or not video data is desired
72 *
73 * @return Boolean to indicate whether any clients need a video frame
74 */
75 inline bool wantsFrame() const
76 {
77 return server->clientHead;
78 }
Eddie James21b177e2018-12-11 13:14:46 -060079 /*
80 * @brief Get the Video object
81 *
82 * @return Reference to the Video object
83 */
84 inline const Video& getVideo() const
85 {
86 return video;
87 }
88
89 private:
Eddie James29f775a2018-12-11 13:22:54 -060090 /*
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070091 * @brief Handler for a client frame update message
92 *
93 * @param[in] cl - Handle to the client object
94 * @param[in] furMsg - Pointer of the FUR message
95 */
96 static void
George Liuf79f6f52022-07-06 09:32:35 +080097 clientFramebufferUpdateRequest(rfbClientPtr cl,
98 rfbFramebufferUpdateRequestMsg* furMsg);
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070099 /*
Eddie James29f775a2018-12-11 13:22:54 -0600100 * @brief Handler for a client disconnecting
101 *
102 * @param[in] cl - Handle to the client object
103 */
104 static void clientGone(rfbClientPtr cl);
105 /*
106 * @brief Handler for client connecting
107 *
108 * @param[in] cl - Handle to the client object
109 */
110 static enum rfbNewClientAction newClient(rfbClientPtr cl);
111
112 /* @brief Performs the resize operation on the framebuffer */
113 void doResize();
114
115 /* @brief Boolean to indicate if a resize operation is on-going */
116 bool pendingResize;
117 /* @brief Number of frames handled since a client connected */
118 int frameCounter;
119 /* @brief Number of connected clients */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800120 unsigned int numClients;
Eddie James29f775a2018-12-11 13:22:54 -0600121 /* @brief Microseconds to process RFB events every frame */
122 long int processTime;
123 /* @brief Handle to the RFB server object */
124 rfbScreenInfoPtr server;
Eddie James21b177e2018-12-11 13:14:46 -0600125 /* @brief Reference to the Input object */
126 Input& input;
127 /* @brief Reference to the Video object */
128 Video& video;
Eddie James29f775a2018-12-11 13:22:54 -0600129 /* @brief Default framebuffer storage */
130 std::vector<char> framebuffer;
Paul Fertser2d2f3da2021-06-18 11:16:43 +0000131 /* @brief Identical frames detection */
132 bool calcFrameCRC;
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800133 /* @brief Cursor bitmap width */
134 static constexpr int cursorWidth = 20;
135 /* @brief Cursor bitmap height */
136 static constexpr int cursorHeight = 20;
137 /* @brief Cursor bitmap */
138 static constexpr char cursor[] = " "
139 " x "
140 " xx "
141 " xxx "
142 " xxxx "
143 " xxxxx "
144 " xxxxxx "
145 " xxxxxxx "
146 " xxxxxxxx "
147 " xxxxxxxxx "
148 " xxxxxxxxxx "
149 " xxxxxxxxxxx "
150 " xxxxxxx "
151 " xxxxxxx "
152 " xxx xxx "
153 " xx xxx "
154 " x xxx "
155 " xxx "
156 " x "
157 " ";
158 /* @brief Cursor bitmap mask */
159 static constexpr char cursorMask[] = " o "
160 "oxo "
161 "oxxo "
162 "oxxxo "
163 "oxxxxo "
164 "oxxxxxo "
165 "oxxxxxxo "
166 "oxxxxxxxo "
167 "oxxxxxxxxo "
168 "oxxxxxxxxxo "
169 "oxxxxxxxxxxo "
170 "oxxxxxxxxxxxo "
171 "oxxxxxxxoooo "
172 "oxxxxxxxo "
173 "oxxxooxxxo "
174 "oxxo oxxxo "
175 "oxo oxxxo "
176 " o oxxxo "
177 " oxo "
178 " o ";
Eddie James21b177e2018-12-11 13:14:46 -0600179};
180
181} // namespace ikvm