mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 23:03:27 +08:00
VNC: Partition/rename some functionality. Add framework to support a reading and writing thread.
This commit is contained in:
@@ -34,13 +34,21 @@ config VNCSERVER_NDISPLAYS
|
||||
Normally this should be one.
|
||||
|
||||
config VNCSERVER_PRIO
|
||||
int "VNC server thread priority"
|
||||
int "VNC server task priority"
|
||||
default 100
|
||||
|
||||
config VNCSERVER_STACKSIZE
|
||||
int "VNC server stack size"
|
||||
default 2048
|
||||
|
||||
config VNCSERVER_UPDATER_PRIO
|
||||
int "VNC updater thread priority"
|
||||
default 100
|
||||
|
||||
config VNCSERVER_UPDATER_STACKSIZE
|
||||
int "VNC updater thread stack size"
|
||||
default 2048
|
||||
|
||||
choice
|
||||
prompt "VNC color format"
|
||||
default VNCSERVER_COLORFMT_RGB16
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
ifeq ($(CONFIG_VNCSERVER),y)
|
||||
|
||||
CSRCS += vnc_server.c vnc_session.c vnc_negotiate.c vnc_fbdev.c
|
||||
CSRCS += vnc_server.c vnc_negotiate.c vnc_updater.c vnc_receiver.c vnc_fbdev.c
|
||||
|
||||
ifeq ($(CONFIG_NX_KBD),y)
|
||||
CSRCS += vnc_keymap.c
|
||||
|
||||
@@ -153,7 +153,7 @@ static int up_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
if (fbinfo != NULL && vinfo != NULL)
|
||||
{
|
||||
session = vnc_find_session(fbinfo->display);
|
||||
if (session == NULL || session->state != VNCSERVER_SCANNING)
|
||||
if (session == NULL || session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
gdbg("ERROR: session is not connected\n");
|
||||
return -ENOTCONN;
|
||||
@@ -165,8 +165,8 @@ static int up_getvideoinfo(FAR struct fb_vtable_s *vtable,
|
||||
*/
|
||||
|
||||
vinfo->fmt = RFB_COLORFMT;
|
||||
vinfo->xres = session->screen.w;
|
||||
vinfo->yres = session->screen.h;
|
||||
vinfo->xres = CONFIG_VNCSERVER_SCREENWIDTH;
|
||||
vinfo->yres = CONFIG_VNCSERVER_SCREENHEIGHT;
|
||||
vinfo->nplanes = 1;
|
||||
|
||||
return OK;
|
||||
@@ -192,7 +192,7 @@ static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
|
||||
if (fbinfo != NULL && pinfo != NULL && planeno == 0)
|
||||
{
|
||||
session = vnc_find_session(fbinfo->display);
|
||||
if (session == NULL || session->state != VNCSERVER_SCANNING)
|
||||
if (session == NULL || session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
gdbg("ERROR: session is not connected\n");
|
||||
return -ENOTCONN;
|
||||
@@ -206,8 +206,8 @@ static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
|
||||
*/
|
||||
|
||||
pinfo->fbmem = (FAR void *)session->fb;
|
||||
pinfo->fblen = (uint32_t)session->stride * CONFIG_VNCSERVER_SCREENWIDTH;
|
||||
pinfo->stride = (fb_coord_t)session->stride;
|
||||
pinfo->fblen = RFB_SIZE;
|
||||
pinfo->stride = RFB_STRIDE;
|
||||
pinfo->bpp = RFB_BITSPERPIXEL;
|
||||
|
||||
return OK;
|
||||
@@ -236,7 +236,7 @@ static int up_getcmap(FAR struct fb_vtable_s *vtable,
|
||||
if (fbinfo != NULL && cmap != NULL)
|
||||
{
|
||||
session = vnc_find_session(fbinfo->display);
|
||||
if (session == NULL || session->state != VNCSERVER_SCANNING)
|
||||
if (session == NULL || session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
gdbg("ERROR: session is not connected\n");
|
||||
return -ENOTCONN;
|
||||
@@ -271,7 +271,7 @@ static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s
|
||||
if (fbinfo != NULL && cmap != NULL)
|
||||
{
|
||||
session = vnc_find_session(fbinfo->display);
|
||||
if (session == NULL || session->state != VNCSERVER_SCANNING)
|
||||
if (session == NULL || session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
gdbg("ERROR: session is not connected\n");
|
||||
return -ENOTCONN;
|
||||
@@ -307,7 +307,7 @@ static int up_getcursor(FAR struct fb_vtable_s *vtable,
|
||||
if (fbinfo != NULL && attrib != NULL)
|
||||
{
|
||||
session = vnc_find_session(fbinfo->display);
|
||||
if (session == NULL || session->state != VNCSERVER_SCANNING)
|
||||
if (session == NULL || session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
gdbg("ERROR: session is not connected\n");
|
||||
return -ENOTCONN;
|
||||
@@ -341,7 +341,7 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable,
|
||||
if (fbinfo != NULL && settings != NULL)
|
||||
{
|
||||
session = vnc_find_session(fbinfo->display);
|
||||
if (session == NULL || session->state != VNCSERVER_SCANNING)
|
||||
if (session == NULL || session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
gdbg("ERROR: session is not connected\n");
|
||||
return -ENOTCONN;
|
||||
@@ -451,7 +451,7 @@ FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
|
||||
|
||||
/* Verify that the session is still valid */
|
||||
|
||||
if (session->state != VNCSERVER_SCANNING)
|
||||
if (session->state != VNCSERVER_RUNNING)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/video/fb.h>
|
||||
#include <nuttx/video/rfb.h>
|
||||
|
||||
@@ -74,8 +73,7 @@ static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8;
|
||||
* properties.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns zero (OK) on success; a negated errno value on failure.
|
||||
@@ -91,7 +89,6 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
FAR struct rfb_setpixelformat_s *setformat;
|
||||
ssize_t nsent;
|
||||
ssize_t nrecvd;
|
||||
size_t alloc;
|
||||
size_t len;
|
||||
int errcode;
|
||||
|
||||
@@ -111,7 +108,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
|
||||
/* Receive the echo of the protocol string */
|
||||
|
||||
nrecvd = psock_recv(&session->connect, session->iobuf, len, 0);
|
||||
nrecvd = psock_recv(&session->connect, session->inbuf, len, 0);
|
||||
if (nrecvd <= 0)
|
||||
{
|
||||
errcode = get_errno();
|
||||
@@ -128,7 +125,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
* word:"
|
||||
*/
|
||||
|
||||
sectype = (FAR struct rfb_sectype_s *)session->iobuf;
|
||||
sectype = (FAR struct rfb_sectype_s *)session->outbuf;
|
||||
rfb_putbe32(sectype->type, RFB_SECTYPE_NONE);
|
||||
|
||||
nsent = psock_send(&session->connect, sectype,
|
||||
@@ -153,7 +150,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
* In this implementation, the sharing flag is ignored.
|
||||
*/
|
||||
|
||||
nrecvd = psock_recv(&session->connect, session->iobuf,
|
||||
nrecvd = psock_recv(&session->connect, session->inbuf,
|
||||
sizeof(struct rfb_clientinit_s), 0);
|
||||
if (nrecvd < 0)
|
||||
{
|
||||
@@ -172,7 +169,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
* framebuffer, its pixel format and the name associated with the desktop:
|
||||
*/
|
||||
|
||||
serverinit = (FAR struct rfb_serverinit_s *)session->iobuf;
|
||||
serverinit = (FAR struct rfb_serverinit_s *)session->outbuf;
|
||||
|
||||
rfb_putbe16(serverinit->width, CONFIG_VNCSERVER_SCREENWIDTH);
|
||||
rfb_putbe16(serverinit->height, CONFIG_VNCSERVER_SCREENHEIGHT);
|
||||
@@ -207,7 +204,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
* This may override some of our framebuffer settings.
|
||||
*/
|
||||
|
||||
setformat = (FAR struct rfb_setpixelformat_s *)session->iobuf;
|
||||
setformat = (FAR struct rfb_setpixelformat_s *)session->inbuf;
|
||||
|
||||
nrecvd = psock_recv(&session->connect, setformat,
|
||||
sizeof(struct rfb_setpixelformat_s), 0);
|
||||
@@ -272,30 +269,11 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
session->screen.w = CONFIG_VNCSERVER_SCREENWIDTH;
|
||||
session->screen.h = CONFIG_VNCSERVER_SCREENHEIGHT;
|
||||
|
||||
/* Now allocate the framebuffer memory. We rely on the fact that
|
||||
* the KMM allocator will align memory to 32-bits or better.
|
||||
*/
|
||||
|
||||
len = (session->bpp + 7) >> 3;
|
||||
session->stride = len * CONFIG_VNCSERVER_SCREENWIDTH;
|
||||
alloc = (size_t)session->stride * CONFIG_VNCSERVER_SCREENHEIGHT;
|
||||
|
||||
session->fb = (FAR uint8_t *)kmm_zalloc(alloc);
|
||||
if (session->fb == NULL)
|
||||
{
|
||||
gdbg("ERROR: Failed to allocate framebuffer memory: %lu\n",
|
||||
(unsigned long)alloc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Receive supported encoding types from client, but ignore them.
|
||||
* we will do only raw format.
|
||||
*/
|
||||
|
||||
(void)psock_recv(&session->connect, session->iobuf,
|
||||
(void)psock_recv(&session->connect, session->inbuf,
|
||||
CONFIG_VNCSERVER_IOBUFFER_SIZE, 0);
|
||||
|
||||
session->state = VNCSERVER_CONFIGURED;
|
||||
@@ -326,7 +304,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
|
||||
|
||||
/* Receive the echo of the protocol string */
|
||||
|
||||
nrecvd = psock_recv(&session->connect, session->iobuf, len, 0);
|
||||
nrecvd = psock_recv(&session->connect, session->inbuf, len, 0);
|
||||
if (nrecvd <= 0)
|
||||
{
|
||||
errcode = get_errno();
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/****************************************************************************
|
||||
* graphics/vnc/vnc_receiver.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "vnc_server.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_receiver
|
||||
*
|
||||
* Description:
|
||||
* This function handles all Client-to-Server messages.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* At present, always returns OK
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_receiver(FAR struct vnc_session_s *session)
|
||||
{
|
||||
#warning Missing logic
|
||||
return -ENOSYS;
|
||||
}
|
||||
@@ -39,12 +39,25 @@
|
||||
|
||||
#include "nuttx/config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "vnc_server.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@@ -55,6 +68,116 @@
|
||||
|
||||
static FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_reset_session
|
||||
*
|
||||
* Description:
|
||||
* Conclude the current VNC session. This function re-initializes the
|
||||
* session structure; it does not free either the session structure nor
|
||||
* the framebuffer so that they may be re-used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void vnc_reset_session(FAR struct vnc_session_s *session,
|
||||
FAR uint8_t *fb)
|
||||
{
|
||||
/* Close any open sockets */
|
||||
|
||||
if (session->state >= VNCSERVER_CONNECTED)
|
||||
{
|
||||
psock_close(&session->connect);
|
||||
psock_close(&session->listen);
|
||||
}
|
||||
|
||||
/* [Re-]nitialize the session. Set all values to 0 == NULL == false. */
|
||||
|
||||
memset(session, 0, sizeof(struct vnc_session_s));
|
||||
|
||||
/* Then initialize only non-zero values */
|
||||
|
||||
session->fb = fb;
|
||||
session->state = VNCSERVER_INITIALIZED;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_connect
|
||||
*
|
||||
* Description:
|
||||
* Wait for a connection from the VNC client
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
* port - The listen port to use
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int vnc_connect(FAR struct vnc_session_s *session, int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
|
||||
/* Create a listening socket */
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
ret = psock_socket(AF_INET, SOCK_STREAM, 0, &session->listen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Bind the listening socket to a local address */
|
||||
|
||||
ret = psock_bind(&session->listen, (struct sockaddr *)&addr,
|
||||
sizeof(struct sockaddr_in));
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
goto errout_with_listener;
|
||||
}
|
||||
|
||||
/* Listen for a connection */
|
||||
|
||||
ret = psock_listen(&session->listen, 5);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
goto errout_with_listener;
|
||||
}
|
||||
|
||||
/* Connect to the client */
|
||||
|
||||
ret = psock_accept(&session->listen, NULL, NULL, &session->connect);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
goto errout_with_listener;
|
||||
}
|
||||
|
||||
session->state = VNCSERVER_CONNECTED;
|
||||
return OK;
|
||||
|
||||
errout_with_listener:
|
||||
psock_close(&session->listen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Pubic Functions
|
||||
****************************************************************************/
|
||||
@@ -76,6 +199,7 @@ static FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS];
|
||||
int vnc_server(int argc, FAR char *argv[])
|
||||
{
|
||||
FAR struct vnc_session_s *session;
|
||||
FAR uint8_t *fb;
|
||||
int display;
|
||||
int ret;
|
||||
|
||||
@@ -96,13 +220,25 @@ int vnc_server(int argc, FAR char *argv[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Allocate the framebuffer memory. We rely on the fact that
|
||||
* the KMM allocator will align memory to 32-bits or better.
|
||||
*/
|
||||
|
||||
fb = (FAR uint8_t *)kmm_zalloc(RFB_SIZE);
|
||||
if (fb == NULL)
|
||||
{
|
||||
gdbg("ERROR: Failed to allocate framebuffer memory: %lu\n",
|
||||
(unsigned long)alloc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Allocate a session structure for this display */
|
||||
|
||||
session = vnc_create_session();
|
||||
session = kmm_zalloc(sizeof(struct vnc_session_s));
|
||||
if (session == NULL)
|
||||
{
|
||||
gdbg("ERROR: Failed to allocate session\n");
|
||||
return EXIT_FAILURE;
|
||||
goto errout_with_fb;
|
||||
}
|
||||
|
||||
g_vnc_sessions[display] = session;
|
||||
@@ -113,6 +249,12 @@ int vnc_server(int argc, FAR char *argv[])
|
||||
|
||||
for (; ; )
|
||||
{
|
||||
/* Release the last sesstion and [Re-]initialize the session structure
|
||||
* for the next connection.
|
||||
*/
|
||||
|
||||
vnc_reset_session(session, fb);
|
||||
|
||||
/* Establish a connection with the VNC client */
|
||||
|
||||
ret = vnc_connect(session, RFB_DISPLAY_PORT(display));
|
||||
@@ -130,24 +272,42 @@ int vnc_server(int argc, FAR char *argv[])
|
||||
{
|
||||
gdbg("ERROR: Failed to negotiate security/framebuffer: %d\n",
|
||||
ret);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Start the VNC session. This function does not return until
|
||||
* the session has been terminated (or an error occurs).
|
||||
*/
|
||||
|
||||
ret = vnc_session(session);
|
||||
gvdbg("Session terminated with %d\n", ret);
|
||||
/* Start the VNC updater thread that sends all Server-to-Client
|
||||
* messages.
|
||||
*/
|
||||
|
||||
ret = vnc_start_updater(session);
|
||||
if (ret < 0)
|
||||
{
|
||||
gdbg("ERROR: Failed to start updater thread: %d\n", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Start the VNC receiver on this this. The VNC receiver handles
|
||||
* all Client-to-Server messages. The VNC receiver function does
|
||||
* not return until the session has been terminated (or an error
|
||||
* occurs).
|
||||
*/
|
||||
|
||||
ret = vnc_receiver(session);
|
||||
gvdbg("Session terminated with %d\n", ret);
|
||||
|
||||
/* Stop the VNC updater thread. */
|
||||
|
||||
ret = vnc_stop_updater(session);
|
||||
if (ret < 0)
|
||||
{
|
||||
gdbg("ERROR: Failed to stop updater thread: %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-initialize the session structure for re-use */
|
||||
|
||||
vnc_release_session(session);
|
||||
}
|
||||
|
||||
return EXIT_FAILURE; /* We won't get here */
|
||||
errout_with_fb:
|
||||
kmm_free(fb);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -160,10 +320,9 @@ int vnc_server(int argc, FAR char *argv[])
|
||||
* display - The display number of interest.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns the instance of the session structure allocated by
|
||||
* vnc_create_session() for this display. NULL will be returned if the
|
||||
* server has not yet been started or if the display number is out of
|
||||
* range.
|
||||
* Returns the instance of the session structure for this display. NULL
|
||||
* will be returned if the server has not yet been started or if the
|
||||
* display number is out of range.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <nuttx/video/fb.h>
|
||||
#include <nuttx/nx/nxglib.h>
|
||||
@@ -109,10 +110,24 @@
|
||||
# define CONFIG_VNCSERVER_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_VNCSERVER_UPDATER_PRIO
|
||||
# define CONFIG_VNCSERVER_UPDATER_PRIO 100
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_VNCSERVER_UPDATER_STACKSIZE
|
||||
# define CONFIG_VNCSERVER_UPDATER_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_VNCSERVER_IOBUFFER_SIZE
|
||||
# define CONFIG_VNCSERVER_IOBUFFER_SIZE 80
|
||||
#endif
|
||||
|
||||
/* Local framebuffer characteristics in bytes */
|
||||
|
||||
#define RFB_BYTESPERPIXEL ((RFB_BITSPERPIXEL + 7) >> 8)
|
||||
#define RFB_STRIDE (RFB_BYTESPERPIXEL * CONFIG_VNCSERVER_SCREENWIDTH)
|
||||
#define RFB_SIZE (RFB_STRIDE * CONFIG_VNCSERVER_SCREENHEIGHT)
|
||||
|
||||
/* RFB Port Number */
|
||||
|
||||
#define RFB_PORT_BASE 5900
|
||||
@@ -141,7 +156,7 @@ enum vnc_server_e
|
||||
VNCSERVER_INITIALIZED, /* State structured initialized, but not connected */
|
||||
VNCSERVER_CONNECTED, /* Connect to a client, but not yet configured */
|
||||
VNCSERVER_CONFIGURED, /* Configured and ready to transfer graphics */
|
||||
VNCSERVER_SCANNING, /* Running and activly transferring graphics */
|
||||
VNCSERVER_RUNNING, /* Running and activly transferring graphics */
|
||||
VNCSERVER_STOPPING /* The server has been asked to stop */
|
||||
};
|
||||
|
||||
@@ -159,15 +174,18 @@ struct vnc_session_s
|
||||
|
||||
/* Display geometry and color characteristics */
|
||||
|
||||
uint8_t colorfmt; /* See include/nuttx/fb.h */
|
||||
uint8_t bpp; /* Bits per pixel */
|
||||
size_t stride; /* Width of a row in bytes */
|
||||
struct nxgl_size_s screen; /* Size of the screen in pixels x rows */
|
||||
uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */
|
||||
uint8_t bpp; /* Remote bits per pixel */
|
||||
FAR uint8_t *fb; /* Allocated local frame buffer */
|
||||
|
||||
/* I/O buffer for misc network send/receive */
|
||||
/* Updater information */
|
||||
|
||||
uint8_t iobuf[CONFIG_VNCSERVER_IOBUFFER_SIZE];
|
||||
pthread_t updater; /* Updater thread ID */
|
||||
|
||||
/* I/O buffers for misc network send/receive */
|
||||
|
||||
uint8_t inbuf[CONFIG_VNCSERVER_IOBUFFER_SIZE];
|
||||
uint8_t outbuf[CONFIG_VNCSERVER_IOBUFFER_SIZE];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@@ -198,60 +216,6 @@ extern "C"
|
||||
|
||||
int vnc_server(int argc, FAR char *argv[]);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_connect
|
||||
*
|
||||
* Description:
|
||||
* Wait for a connection from the VNC client
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
* port - The listen port to use
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_connect(FAR struct vnc_session_s *session, int port);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_create_session
|
||||
*
|
||||
* Description:
|
||||
* Create a new, unconnected session
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, this function returns the allocated and initialize session
|
||||
* structure. NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct vnc_session_s *vnc_create_session(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_release_session
|
||||
*
|
||||
* Description:
|
||||
* Conclude the current VNC session and free most resources. This function
|
||||
* re-initializes the session structure; it does not free it so that it
|
||||
* can be re-used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void vnc_release_session(FAR struct vnc_session_s *session);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_negotiate
|
||||
*
|
||||
@@ -261,8 +225,7 @@ void vnc_release_session(FAR struct vnc_session_s *session);
|
||||
* properties.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns zero (OK) on success; a negated errno value on failure.
|
||||
@@ -272,40 +235,54 @@ void vnc_release_session(FAR struct vnc_session_s *session);
|
||||
int vnc_negotiate(FAR struct vnc_session_s *session);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_session
|
||||
* Name: vnc_start_updater
|
||||
*
|
||||
* Description:
|
||||
* This function encapsulates the entire VNC session.
|
||||
* Start the updater thread
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_start_updater(FAR struct vnc_session_s *session);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_stop_updater
|
||||
*
|
||||
* Description:
|
||||
* Stop the updater thread
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_stop_updater(FAR struct vnc_session_s *session);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_receiver
|
||||
*
|
||||
* Description:
|
||||
* This function handles all Client-to-Server messages.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* At present, always returns OK
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_session(FAR struct vnc_session_s *session);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_find_session
|
||||
*
|
||||
* Description:
|
||||
* Return the session structure associated with this display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - The display number of interest.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns the instance of the session structure allocated by
|
||||
* vnc_create_session() for this display. NULL will be returned if the
|
||||
* server has not yet been started or if the display number is out of
|
||||
* range.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct vnc_session_s *vnc_find_session(int display);
|
||||
int vnc_receiver(FAR struct vnc_session_s *session);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_key_map
|
||||
@@ -315,8 +292,7 @@ FAR struct vnc_session_s *vnc_find_session(int display);
|
||||
* that through NX to the appropriate window.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
* session - An instance of the session structure.
|
||||
* keysym - The X11 keysym value (see include/nuttx/inputx11_keysymdef)
|
||||
* keydown - True: Key pressed; False: Key released
|
||||
*
|
||||
@@ -330,6 +306,24 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint32_t keysym,
|
||||
bool keydown);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_find_session
|
||||
*
|
||||
* Description:
|
||||
* Return the session structure associated with this display.
|
||||
*
|
||||
* Input Parameters:
|
||||
* display - The display number of interest.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns the instance of the session structure for this display. NULL
|
||||
* will be returned if the server has not yet been started or if the
|
||||
* display number is out of range.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct vnc_session_s *vnc_find_session(int display);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
/****************************************************************************
|
||||
* graphics/vnc/vnc_session.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/net/net.h>
|
||||
|
||||
#include "vnc_server.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_initialize_session
|
||||
*
|
||||
* Description:
|
||||
* [Re-]initialize a VNC session
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - the VNC session to be initialized
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void vnc_initialize_session(FAR struct vnc_session_s *session)
|
||||
{
|
||||
/* Initialize the session. Set all values to 0 == NULL == false. */
|
||||
|
||||
memset(session, 0, sizeof(struct vnc_session_s));
|
||||
|
||||
/* Then initialize only non-zero values */
|
||||
/* Initialized, not connected */
|
||||
|
||||
session->state = VNCSERVER_INITIALIZED;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_connect
|
||||
*
|
||||
* Description:
|
||||
* Wait for a connection from the VNC client
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
* port - The listen port to use
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_connect(FAR struct vnc_session_s *session, int port)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int ret;
|
||||
|
||||
/* Create a listening socket */
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
ret = psock_socket(AF_INET, SOCK_STREAM, 0, &session->listen);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Bind the listening socket to a local address */
|
||||
|
||||
ret = psock_bind(&session->listen, (struct sockaddr *)&addr,
|
||||
sizeof(struct sockaddr_in));
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
goto errout_with_listener;
|
||||
}
|
||||
|
||||
/* Listen for a connection */
|
||||
|
||||
ret = psock_listen(&session->listen, 5);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
goto errout_with_listener;
|
||||
}
|
||||
|
||||
/* Connect to the client */
|
||||
|
||||
ret = psock_accept(&session->listen, NULL, NULL, &session->connect);
|
||||
if (ret < 0)
|
||||
{
|
||||
ret = -get_errno();
|
||||
goto errout_with_listener;
|
||||
}
|
||||
|
||||
session->state = VNCSERVER_CONNECTED;
|
||||
return OK;
|
||||
|
||||
errout_with_listener:
|
||||
psock_close(&session->listen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_create_session
|
||||
*
|
||||
* Description:
|
||||
* Create a new, unconnected session
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* On success, this function returns the allocated and initialize session
|
||||
* structure. NULL is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct vnc_session_s *vnc_create_session(void)
|
||||
{
|
||||
FAR struct vnc_session_s *session;
|
||||
|
||||
/* Allocate the session */
|
||||
|
||||
session = (FAR struct vnc_session_s *)
|
||||
kmm_zalloc(sizeof(struct vnc_session_s));
|
||||
|
||||
/* Initialize the session */
|
||||
|
||||
if (session != NULL)
|
||||
{
|
||||
vnc_initialize_session(session);
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_release_session
|
||||
*
|
||||
* Description:
|
||||
* Conclude the current VNC session and free most resources. This function
|
||||
* re-initializes the session structure; it does not free it so that it
|
||||
* can be re-used.
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure allocated by
|
||||
* vnc_create_session().
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void vnc_release_session(FAR struct vnc_session_s *session)
|
||||
{
|
||||
/* Close any open sockets */
|
||||
|
||||
if (session->state >= VNCSERVER_CONNECTED)
|
||||
{
|
||||
psock_close(&session->connect);
|
||||
psock_close(&session->listen);
|
||||
}
|
||||
|
||||
/* Free the allocated framebuffer */
|
||||
|
||||
if (session->fb)
|
||||
{
|
||||
kmm_free(session->fb);
|
||||
}
|
||||
|
||||
vnc_initialize_session(session);
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/****************************************************************************
|
||||
* graphics/vnc/vnc_updater.c
|
||||
*
|
||||
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sched.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "vnc_server.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_updater
|
||||
*
|
||||
* Description:
|
||||
* This is the "updater" thread. It is the sender of all Server-to-Client
|
||||
* messages
|
||||
*
|
||||
* Input Parameters:
|
||||
* Standard pthread arguments.
|
||||
*
|
||||
* Returned Value:
|
||||
* NULL is always returned.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static FAR void *vnc_updater(FAR void *arg)
|
||||
{
|
||||
FAR struct vnc_session_s *session = (FAR struct vnc_session_s *)arg;
|
||||
|
||||
DEBUGASSERT(session != NULL);
|
||||
|
||||
while (session->state == VNCSERVER_RUNNING)
|
||||
{
|
||||
#warning Missing logic
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_start_updater
|
||||
*
|
||||
* Description:
|
||||
* Start the updater thread
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_start_updater(FAR struct vnc_session_s *session)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
struct sched_param param;
|
||||
int status;
|
||||
|
||||
/* Create thread that is gonna send rectangles to the client */
|
||||
|
||||
session->state = VNCSERVER_RUNNING;
|
||||
|
||||
DEBUGVERIFY(pthread_attr_init(&attr));
|
||||
DEBUGVERIFY(pthread_attr_setstacksize(&attr, CONFIG_VNCSERVER_UPDATER_STACKSIZE));
|
||||
|
||||
param.sched_priority = CONFIG_VNCSERVER_UPDATER_PRIO;
|
||||
DEBUGVERIFY(pthread_attr_setschedparam(&attr, ¶m));
|
||||
|
||||
status = pthread_create(&session->updater, &attr, vnc_updater,
|
||||
(pthread_addr_t)session);
|
||||
if (status != 0)
|
||||
{
|
||||
return -status;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: vnc_stop_updater
|
||||
*
|
||||
* Description:
|
||||
* Stop the updater thread
|
||||
*
|
||||
* Input Parameters:
|
||||
* session - An instance of the session structure.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned on
|
||||
* any failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int vnc_stop_updater(FAR struct vnc_session_s *session)
|
||||
{
|
||||
pthread_addr_t result;
|
||||
int status;
|
||||
|
||||
/* Is the update thread running? */
|
||||
|
||||
if (session->state == VNCSERVER_RUNNING)
|
||||
{
|
||||
/* Yes.. ask it to please stop */
|
||||
|
||||
session->state = VNCSERVER_STOPPING;
|
||||
|
||||
/* Wait for the thread to comply with our request */
|
||||
|
||||
status = pthread_join(session->updater, &result);
|
||||
if (status != 0)
|
||||
{
|
||||
return -status;
|
||||
}
|
||||
|
||||
/* Return what the thread returned */
|
||||
|
||||
return (int)((intptr_t)result);
|
||||
}
|
||||
|
||||
/* Not running? Just say we stopped the thread successfully. */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user