xref: /openbmc/obmc-ikvm/ikvm_server.hpp (revision 94f5f422b6b862606ca96108c2538ed32c5ec104)
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