mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
Add handshake to coordintate with connection of VNC client. fb_initialize() will not return until the connection is established
This commit is contained in:
@@ -123,9 +123,7 @@ static struct fb_cursorsize_s g_csize;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The framebuffer object -- There is no private state information in this simple
|
/* The framebuffer objects, one for each configured display. */
|
||||||
* framebuffer simulation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static struct vnc_fbinfo_s g_fbinfo[RFB_MAX_DISPLAYS];
|
static struct vnc_fbinfo_s g_fbinfo[RFB_MAX_DISPLAYS];
|
||||||
|
|
||||||
@@ -133,6 +131,13 @@ static struct vnc_fbinfo_s g_fbinfo[RFB_MAX_DISPLAYS];
|
|||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Used to synchronize the server thread with the framebuffer driver.
|
||||||
|
* NOTE: This depends on the fact that all zero is correct initial state
|
||||||
|
* for the semaphores.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sem_t g_fbsem[RFB_MAX_DISPLAYS];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -324,7 +329,7 @@ static int up_getcursor(FAR struct fb_vtable_s *vtable,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name:
|
* Name: up_setcursor
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_FB_HWCURSOR
|
#ifdef CONFIG_FB_HWCURSOR
|
||||||
@@ -374,6 +379,57 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: vnc_wait_server
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Wait for the server to be connected to the VNC client. We can do
|
||||||
|
* nothing until that connection is established.
|
||||||
|
*
|
||||||
|
* Input parameters:
|
||||||
|
* display - In the case of hardware with multiple displays, this
|
||||||
|
* specifies the display. Normally this is zero.
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int vnc_wait_server(int display)
|
||||||
|
{
|
||||||
|
/* Check if there has been a session allocated yet. This is one of the
|
||||||
|
* first things that the VNC server will do with the kernel thread is
|
||||||
|
* started. But we might be here before the thread has gotten that far.
|
||||||
|
*
|
||||||
|
* If it has been allocated, then wait until it is in the RUNNING state.
|
||||||
|
* The RUNNING state indicates that the server has started, it has
|
||||||
|
* established a connection with the VNC client, it is negotiated
|
||||||
|
* encodings and framebuffer characteristics, and it has started the
|
||||||
|
* updater thread. The server is now ready to recieve Client-to-Server
|
||||||
|
* messages and to perform remote framebuffer updates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (g_vnc_sessions[display] == NULL ||
|
||||||
|
g_vnc_sessions[display]->state != VNCSERVER_RUNNING)
|
||||||
|
{
|
||||||
|
/* The server is not yet running. Wait for the server to post the FB
|
||||||
|
* semaphore. In certain error situations, the server may post the
|
||||||
|
* semaphore, then reset it to zero. There are are certainly race
|
||||||
|
* conditions here, but I think none that are fatal.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (sem_wait(&g_fbsem[display]) < 0)
|
||||||
|
{
|
||||||
|
/* sem_wait() should fail only if it is interrupt by a signal. */
|
||||||
|
|
||||||
|
DEBUGASSERT(get_errno() == EINTR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -408,23 +464,33 @@ int up_fbinitialize(int display)
|
|||||||
gvdbg("Starting the VNC server for display %d\n", display);
|
gvdbg("Starting the VNC server for display %d\n", display);
|
||||||
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
|
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
|
||||||
|
|
||||||
(void)itoa(display, str, 10);
|
/* Check if the server is already running */
|
||||||
argv[0] = str;
|
|
||||||
argv[1] = NULL;
|
|
||||||
|
|
||||||
pid = kernel_thread("vnc_server", CONFIG_VNCSERVER_PRIO,
|
if (g_vnc_sessions[display] != NULL)
|
||||||
CONFIG_VNCSERVER_STACKSIZE,
|
|
||||||
(main_t)vnc_server, argv);
|
|
||||||
if (pid < 0)
|
|
||||||
{
|
{
|
||||||
gdbg("ERROR: Failed to start the VNC server: %d\n", (int)pid);
|
DEBUGASSERT(g_vnc_sessions[display]->state >= VNCSERVER_INITIALIZED);
|
||||||
return (int)pid;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Format the kernel thread arguments (ASCII.. yech) */
|
||||||
|
|
||||||
|
(void)itoa(display, str, 10);
|
||||||
|
argv[0] = str;
|
||||||
|
argv[1] = NULL;
|
||||||
|
|
||||||
|
pid = kernel_thread("vnc_server", CONFIG_VNCSERVER_PRIO,
|
||||||
|
CONFIG_VNCSERVER_STACKSIZE,
|
||||||
|
(main_t)vnc_server, argv);
|
||||||
|
if (pid < 0)
|
||||||
|
{
|
||||||
|
gdbg("ERROR: Failed to start the VNC server: %d\n", (int)pid);
|
||||||
|
return (int)pid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the VNC client to connect and for the RFB to be ready */
|
/* Wait for the VNC client to connect and for the RFB to be ready */
|
||||||
#warning Missing logic
|
|
||||||
|
|
||||||
return OK;
|
return vnc_wait_server(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -503,6 +569,7 @@ FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
|||||||
|
|
||||||
void up_fbuninitialize(int display)
|
void up_fbuninitialize(int display)
|
||||||
{
|
{
|
||||||
|
#if 0 /* Do nothing */
|
||||||
FAR struct vnc_session_s *session = vnc_find_session(display);
|
FAR struct vnc_session_s *session = vnc_find_session(display);
|
||||||
FAR struct vnc_fbinfo_s *fbinfo;
|
FAR struct vnc_fbinfo_s *fbinfo;
|
||||||
|
|
||||||
@@ -511,6 +578,7 @@ void up_fbuninitialize(int display)
|
|||||||
#warning Missing logic
|
#warning Missing logic
|
||||||
UNUSED(session);
|
UNUSED(session);
|
||||||
UNUSED(fbinfo);
|
UNUSED(fbinfo);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
/* REVISIT: SetPixelFormat is currently ignored */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -198,7 +198,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
/* REVISIT: SetEncodings is currently ignored */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -353,7 +353,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#warning Missing logic
|
/* REVISIT: ClientCutText is currently ignored */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,14 +62,14 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Given a display number as an index, the following array can be used to
|
/* Given a display number as an index, the following array can be used to
|
||||||
* look-up the session structure for that display.
|
* look-up the session structure for that display.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
|
FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@@ -281,6 +281,7 @@ int vnc_server(int argc, FAR char *argv[])
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
vnc_reset_session(session, fb);
|
vnc_reset_session(session, fb);
|
||||||
|
sem_reset(&g_fbsem[display], 0);
|
||||||
|
|
||||||
/* Establish a connection with the VNC client */
|
/* Establish a connection with the VNC client */
|
||||||
|
|
||||||
@@ -313,7 +314,13 @@ int vnc_server(int argc, FAR char *argv[])
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the VNC receiver on this this. The VNC receiver handles
|
/* Let the framebuffer driver know that we are ready to preform
|
||||||
|
* updates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sem_post(&g_fbsem[display]);
|
||||||
|
|
||||||
|
/* Run the VNC receiver on this trhead. The VNC receiver handles
|
||||||
* all Client-to-Server messages. The VNC receiver function does
|
* all Client-to-Server messages. The VNC receiver function does
|
||||||
* not return until the session has been terminated (or an error
|
* not return until the session has been terminated (or an error
|
||||||
* occurs).
|
* occurs).
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ struct vnc_session_s
|
|||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -241,6 +241,20 @@ extern "C"
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Given a display number as an index, the following array can be used to
|
||||||
|
* look-up the session structure for that display.
|
||||||
|
*/
|
||||||
|
|
||||||
|
EXTERN FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
|
||||||
|
|
||||||
|
/* Used to synchronize the server thread with the framebuffer driver. */
|
||||||
|
|
||||||
|
EXTERN sem_t g_fbsem[RFB_MAX_DISPLAYS];
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Function Prototypes
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: vnc_server
|
* Name: vnc_server
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user