121b177e0SEddie James #pragma once 221b177e0SEddie James 321b177e0SEddie James #include "ikvm_args.hpp" 421b177e0SEddie James #include "ikvm_input.hpp" 521b177e0SEddie James #include "ikvm_video.hpp" 621b177e0SEddie James 729f775abSEddie James #include <rfb/rfb.h> 829f775abSEddie James 929f775abSEddie James #include <vector> 1029f775abSEddie James 1121b177e0SEddie James namespace ikvm 1221b177e0SEddie James { 1321b177e0SEddie James /* 1421b177e0SEddie James * @class Server 1521b177e0SEddie James * @brief Manages the RFB server connection and updates 1621b177e0SEddie James */ 1721b177e0SEddie James class Server 1821b177e0SEddie James { 1921b177e0SEddie James public: 2021b177e0SEddie James /* 2121b177e0SEddie James * @struct ClientData 2221b177e0SEddie James * @brief Store necessary data for each connected RFB client 2321b177e0SEddie James */ 2421b177e0SEddie James struct ClientData 2521b177e0SEddie James { 2621b177e0SEddie James /* 2721b177e0SEddie James * @brief Constructs ClientData object 2821b177e0SEddie James * 2921b177e0SEddie James * @param[in] s - Number of frames to skip when client connects 3021b177e0SEddie James * @param[in] i - Pointer to Input object 3121b177e0SEddie James */ ClientDataikvm::Server::ClientData322d2f3dabSPaul Fertser ClientData(int s, Input* i) : skipFrame(s), input(i), last_crc{-1} 3321b177e0SEddie James { 3485d04552SJae Hyun Yoo needUpdate = false; 3521b177e0SEddie James } 3621b177e0SEddie James ~ClientData() = default; 3721b177e0SEddie James ClientData(const ClientData&) = default; 3821b177e0SEddie James ClientData& operator=(const ClientData&) = default; 3921b177e0SEddie James ClientData(ClientData&&) = default; 4021b177e0SEddie James ClientData& operator=(ClientData&&) = default; 4121b177e0SEddie James 4221b177e0SEddie James int skipFrame; 4321b177e0SEddie James Input* input; 4485d04552SJae Hyun Yoo bool needUpdate; 452d2f3dabSPaul Fertser int64_t last_crc; 4621b177e0SEddie James }; 4721b177e0SEddie James 4821b177e0SEddie James /* 4921b177e0SEddie James * @brief Constructs Server object 5021b177e0SEddie James * 5121b177e0SEddie James * @param[in] args - Reference to Args object 5221b177e0SEddie James * @param[in] i - Reference to Input object 5321b177e0SEddie James * @param[in] v - Reference to Video object 5421b177e0SEddie James */ 5521b177e0SEddie James Server(const Args& args, Input& i, Video& v); 5621b177e0SEddie James ~Server(); 5721b177e0SEddie James Server(const Server&) = default; 5821b177e0SEddie James Server& operator=(const Server&) = default; 5921b177e0SEddie James Server(Server&&) = default; 6021b177e0SEddie James Server& operator=(Server&&) = default; 6121b177e0SEddie James 6229f775abSEddie James /* @brief Resizes the RFB framebuffer */ 6329f775abSEddie James void resize(); 6429f775abSEddie James /* @brief Executes any pending RFB updates and client input */ 6529f775abSEddie James void run(); 6629f775abSEddie James /* @brief Sends pending video frame to clients */ 6729f775abSEddie James void sendFrame(); 6829f775abSEddie James 6929f775abSEddie James /* 7029f775abSEddie James * @brief Indicates whether or not video data is desired 7129f775abSEddie James * 7229f775abSEddie James * @return Boolean to indicate whether any clients need a video frame 7329f775abSEddie James */ wantsFrame() const7429f775abSEddie James inline bool wantsFrame() const 7529f775abSEddie James { 7629f775abSEddie James return server->clientHead; 7729f775abSEddie James } 7821b177e0SEddie James /* 7921b177e0SEddie James * @brief Get the Video object 8021b177e0SEddie James * 8121b177e0SEddie James * @return Reference to the Video object 8221b177e0SEddie James */ getVideo() const8321b177e0SEddie James inline const Video& getVideo() const 8421b177e0SEddie James { 8521b177e0SEddie James return video; 8621b177e0SEddie James } 8721b177e0SEddie James 8821b177e0SEddie James private: 8929f775abSEddie James /* 9085d04552SJae Hyun Yoo * @brief Handler for a client frame update message 9185d04552SJae Hyun Yoo * 9285d04552SJae Hyun Yoo * @param[in] cl - Handle to the client object 9385d04552SJae Hyun Yoo * @param[in] furMsg - Pointer of the FUR message 9485d04552SJae Hyun Yoo */ 95*94f5f422SPatrick Williams static void clientFramebufferUpdateRequest( 96*94f5f422SPatrick Williams rfbClientPtr cl, rfbFramebufferUpdateRequestMsg* furMsg); 9785d04552SJae Hyun Yoo /* 9829f775abSEddie James * @brief Handler for a client disconnecting 9929f775abSEddie James * 10029f775abSEddie James * @param[in] cl - Handle to the client object 10129f775abSEddie James */ 10229f775abSEddie James static void clientGone(rfbClientPtr cl); 10329f775abSEddie James /* 10429f775abSEddie James * @brief Handler for client connecting 10529f775abSEddie James * 10629f775abSEddie James * @param[in] cl - Handle to the client object 10729f775abSEddie James */ 10829f775abSEddie James static enum rfbNewClientAction newClient(rfbClientPtr cl); 10929f775abSEddie James 11029f775abSEddie James /* @brief Performs the resize operation on the framebuffer */ 11129f775abSEddie James void doResize(); 11229f775abSEddie James 11329f775abSEddie James /* @brief Boolean to indicate if a resize operation is on-going */ 11429f775abSEddie James bool pendingResize; 11529f775abSEddie James /* @brief Number of frames handled since a client connected */ 11629f775abSEddie James int frameCounter; 11729f775abSEddie James /* @brief Number of connected clients */ 1187dfac9ffSJae Hyun Yoo unsigned int numClients; 11929f775abSEddie James /* @brief Microseconds to process RFB events every frame */ 12029f775abSEddie James long int processTime; 12129f775abSEddie James /* @brief Handle to the RFB server object */ 12229f775abSEddie James rfbScreenInfoPtr server; 12321b177e0SEddie James /* @brief Reference to the Input object */ 12421b177e0SEddie James Input& input; 12521b177e0SEddie James /* @brief Reference to the Video object */ 12621b177e0SEddie James Video& video; 12729f775abSEddie James /* @brief Default framebuffer storage */ 12829f775abSEddie James std::vector<char> framebuffer; 1292d2f3dabSPaul Fertser /* @brief Identical frames detection */ 1302d2f3dabSPaul Fertser bool calcFrameCRC; 1317dfac9ffSJae Hyun Yoo /* @brief Cursor bitmap width */ 1327dfac9ffSJae Hyun Yoo static constexpr int cursorWidth = 20; 1337dfac9ffSJae Hyun Yoo /* @brief Cursor bitmap height */ 1347dfac9ffSJae Hyun Yoo static constexpr int cursorHeight = 20; 1357dfac9ffSJae Hyun Yoo /* @brief Cursor bitmap */ 136*94f5f422SPatrick Williams static constexpr char cursor[] = 137*94f5f422SPatrick Williams " " 1387dfac9ffSJae Hyun Yoo " x " 1397dfac9ffSJae Hyun Yoo " xx " 1407dfac9ffSJae Hyun Yoo " xxx " 1417dfac9ffSJae Hyun Yoo " xxxx " 1427dfac9ffSJae Hyun Yoo " xxxxx " 1437dfac9ffSJae Hyun Yoo " xxxxxx " 1447dfac9ffSJae Hyun Yoo " xxxxxxx " 1457dfac9ffSJae Hyun Yoo " xxxxxxxx " 1467dfac9ffSJae Hyun Yoo " xxxxxxxxx " 1477dfac9ffSJae Hyun Yoo " xxxxxxxxxx " 1487dfac9ffSJae Hyun Yoo " xxxxxxxxxxx " 1497dfac9ffSJae Hyun Yoo " xxxxxxx " 1507dfac9ffSJae Hyun Yoo " xxxxxxx " 1517dfac9ffSJae Hyun Yoo " xxx xxx " 1527dfac9ffSJae Hyun Yoo " xx xxx " 1537dfac9ffSJae Hyun Yoo " x xxx " 1547dfac9ffSJae Hyun Yoo " xxx " 1557dfac9ffSJae Hyun Yoo " x " 1567dfac9ffSJae Hyun Yoo " "; 1577dfac9ffSJae Hyun Yoo /* @brief Cursor bitmap mask */ 158*94f5f422SPatrick Williams static constexpr char cursorMask[] = 159*94f5f422SPatrick Williams " o " 1607dfac9ffSJae Hyun Yoo "oxo " 1617dfac9ffSJae Hyun Yoo "oxxo " 1627dfac9ffSJae Hyun Yoo "oxxxo " 1637dfac9ffSJae Hyun Yoo "oxxxxo " 1647dfac9ffSJae Hyun Yoo "oxxxxxo " 1657dfac9ffSJae Hyun Yoo "oxxxxxxo " 1667dfac9ffSJae Hyun Yoo "oxxxxxxxo " 1677dfac9ffSJae Hyun Yoo "oxxxxxxxxo " 1687dfac9ffSJae Hyun Yoo "oxxxxxxxxxo " 1697dfac9ffSJae Hyun Yoo "oxxxxxxxxxxo " 1707dfac9ffSJae Hyun Yoo "oxxxxxxxxxxxo " 1717dfac9ffSJae Hyun Yoo "oxxxxxxxoooo " 1727dfac9ffSJae Hyun Yoo "oxxxxxxxo " 1737dfac9ffSJae Hyun Yoo "oxxxooxxxo " 1747dfac9ffSJae Hyun Yoo "oxxo oxxxo " 1757dfac9ffSJae Hyun Yoo "oxo oxxxo " 1767dfac9ffSJae Hyun Yoo " o oxxxo " 1777dfac9ffSJae Hyun Yoo " oxo " 1787dfac9ffSJae Hyun Yoo " o "; 17921b177e0SEddie James }; 18021b177e0SEddie James 18121b177e0SEddie James } // namespace ikvm 182