blob: bc055f3dac4866209b45cef4312f6a7b589e943b [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{
Eddie James21b177e2018-12-11 13:14:46 -060013/*
14 * @class Server
15 * @brief Manages the RFB server connection and updates
16 */
17class Server
18{
19 public:
20 /*
21 * @struct ClientData
22 * @brief Store necessary data for each connected RFB client
23 */
24 struct ClientData
25 {
26 /*
27 * @brief Constructs ClientData object
28 *
29 * @param[in] s - Number of frames to skip when client connects
30 * @param[in] i - Pointer to Input object
31 */
Paul Fertser2d2f3da2021-06-18 11:16:43 +000032 ClientData(int s, Input* i) : skipFrame(s), input(i), last_crc{-1}
Eddie James21b177e2018-12-11 13:14:46 -060033 {
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070034 needUpdate = false;
Eddie James21b177e2018-12-11 13:14:46 -060035 }
36 ~ClientData() = default;
37 ClientData(const ClientData&) = default;
38 ClientData& operator=(const ClientData&) = default;
39 ClientData(ClientData&&) = default;
40 ClientData& operator=(ClientData&&) = default;
41
42 int skipFrame;
43 Input* input;
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070044 bool needUpdate;
Paul Fertser2d2f3da2021-06-18 11:16:43 +000045 int64_t last_crc;
Eddie James21b177e2018-12-11 13:14:46 -060046 };
47
48 /*
49 * @brief Constructs Server object
50 *
51 * @param[in] args - Reference to Args object
52 * @param[in] i - Reference to Input object
53 * @param[in] v - Reference to Video object
54 */
55 Server(const Args& args, Input& i, Video& v);
56 ~Server();
57 Server(const Server&) = default;
58 Server& operator=(const Server&) = default;
59 Server(Server&&) = default;
60 Server& operator=(Server&&) = default;
61
Eddie James29f775a2018-12-11 13:22:54 -060062 /* @brief Resizes the RFB framebuffer */
63 void resize();
64 /* @brief Executes any pending RFB updates and client input */
65 void run();
66 /* @brief Sends pending video frame to clients */
67 void sendFrame();
68
69 /*
70 * @brief Indicates whether or not video data is desired
71 *
72 * @return Boolean to indicate whether any clients need a video frame
73 */
74 inline bool wantsFrame() const
75 {
76 return server->clientHead;
77 }
Eddie James21b177e2018-12-11 13:14:46 -060078 /*
79 * @brief Get the Video object
80 *
81 * @return Reference to the Video object
82 */
83 inline const Video& getVideo() const
84 {
85 return video;
86 }
87
88 private:
Eddie James29f775a2018-12-11 13:22:54 -060089 /*
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070090 * @brief Handler for a client frame update message
91 *
92 * @param[in] cl - Handle to the client object
93 * @param[in] furMsg - Pointer of the FUR message
94 */
Patrick Williams94f5f422024-08-16 15:22:08 -040095 static void clientFramebufferUpdateRequest(
96 rfbClientPtr cl, rfbFramebufferUpdateRequestMsg* furMsg);
Jae Hyun Yoo85d04552019-05-09 16:26:53 -070097 /*
Eddie James29f775a2018-12-11 13:22:54 -060098 * @brief Handler for a client disconnecting
99 *
100 * @param[in] cl - Handle to the client object
101 */
102 static void clientGone(rfbClientPtr cl);
103 /*
104 * @brief Handler for client connecting
105 *
106 * @param[in] cl - Handle to the client object
107 */
108 static enum rfbNewClientAction newClient(rfbClientPtr cl);
109
110 /* @brief Performs the resize operation on the framebuffer */
111 void doResize();
112
113 /* @brief Boolean to indicate if a resize operation is on-going */
114 bool pendingResize;
115 /* @brief Number of frames handled since a client connected */
116 int frameCounter;
117 /* @brief Number of connected clients */
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800118 unsigned int numClients;
Eddie James29f775a2018-12-11 13:22:54 -0600119 /* @brief Microseconds to process RFB events every frame */
120 long int processTime;
121 /* @brief Handle to the RFB server object */
122 rfbScreenInfoPtr server;
Eddie James21b177e2018-12-11 13:14:46 -0600123 /* @brief Reference to the Input object */
124 Input& input;
125 /* @brief Reference to the Video object */
126 Video& video;
Eddie James29f775a2018-12-11 13:22:54 -0600127 /* @brief Default framebuffer storage */
128 std::vector<char> framebuffer;
Paul Fertser2d2f3da2021-06-18 11:16:43 +0000129 /* @brief Identical frames detection */
130 bool calcFrameCRC;
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800131 /* @brief Cursor bitmap width */
132 static constexpr int cursorWidth = 20;
133 /* @brief Cursor bitmap height */
134 static constexpr int cursorHeight = 20;
135 /* @brief Cursor bitmap */
Patrick Williams94f5f422024-08-16 15:22:08 -0400136 static constexpr char cursor[] =
137 " "
138 " x "
139 " xx "
140 " xxx "
141 " xxxx "
142 " xxxxx "
143 " xxxxxx "
144 " xxxxxxx "
145 " xxxxxxxx "
146 " xxxxxxxxx "
147 " xxxxxxxxxx "
148 " xxxxxxxxxxx "
149 " xxxxxxx "
150 " xxxxxxx "
151 " xxx xxx "
152 " xx xxx "
153 " x xxx "
154 " xxx "
155 " x "
156 " ";
Jae Hyun Yoo7dfac9f2019-01-15 10:14:59 -0800157 /* @brief Cursor bitmap mask */
Patrick Williams94f5f422024-08-16 15:22:08 -0400158 static constexpr char cursorMask[] =
159 " 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