Merge branch 'vnc'

This commit is contained in:
Gregory Nutt
2016-04-18 10:53:58 -06:00
17 changed files with 3768 additions and 1 deletions
+3
View File
@@ -745,4 +745,7 @@ config NXSTART_VPLANE
endif # NX_NXSTART
endif # NX_MULTIUSER
source "graphics/vnc/Kconfig"
endif # NX
+1
View File
@@ -50,6 +50,7 @@ include nxbe/Make.defs
include nxmu/Make.defs
include nxsu/Make.defs
include nxterm/Make.defs
include vnc/Make.defs
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
+6
View File
@@ -112,6 +112,10 @@ nuttx/../NxWidgets
The NxWidgets code is provided as a separate package located outside of the
NuttX source tree (probably at this location).
graphics/vnc
The future home of the VNC Remote Frame Buffer (RFB) server and client
implementations.
Installing New Fonts
^^^^^^^^^^^^^^^^^^^^
@@ -295,6 +299,8 @@ CONFIG_NXTK_AUTORAISE
CONFIG_NXFONTS_CHARBITS
The number of bits in the character set. Current options are only 7 and 8.
The default is 7.
CONFIG_VNCSERVER and CONFIG_VNCCLIENT
Enable the VNC RFB server and client, respecitively.
Font Selections
---------------
+7
View File
@@ -0,0 +1,7 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
source "graphics/vnc/server/Kconfig"
source "graphics/vnc/client/Kconfig"
+37
View File
@@ -0,0 +1,37 @@
############################################################################
# graphics/vnc/Make.defs
#
# 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.
#
############################################################################
include vnc/server/Make.defs
include vnc/client/Make.defs
+15
View File
@@ -0,0 +1,15 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menuconfig VNCCLIENT
bool "VNC client"
default n
depends on NET_TCP && !NX_LCDDRIVER && !VNC_SERVER && EXPERIMENTAL
---help---
Enable support for a VNC Remote Frame Buffer (RFB) client
if VNCCLIENT
endif # VNCCLIENT
+42
View File
@@ -0,0 +1,42 @@
############################################################################
# graphics/vnc/client/Make.defs
#
# 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.
#
############################################################################
ifeq ($(CONFIG_VNCCLIENT),y)
DEPPATH += --dep-path vnc/client
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/vnc/client}
VPATH += :vnc/client
endif
+106
View File
@@ -0,0 +1,106 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menuconfig VNCSERVER
bool "VNC server"
default n
depends on NET_TCP && !NX_LCDDRIVER && EXPERIMENTAL
select NET_TCP_READAHEAD
select NX_UPDATE
---help---
Enable support for a VNC Remote Frame Buffer (RFB) server.
if VNCSERVER
choice
prompt "VNC server protocol"
default VNCSERVER_PROTO3p3
config VNCSERVER_PROTO3p3
bool "Version 3.3"
config VNCSERVER_PROTO3p8
bool "Version 3.8"
depends on EXPERIMENTAL
endchoice # VNC server protocol
config VNCSERVER_NDISPLAYS
int "Number of displays"
default 1
range 1 99
---help---
Specifies the number of RFB displays supported by the server.
Normally this should be one.
config VNCSERVER_PRIO
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
config VNCSERVER_COLORFMT_RGB16
bool "RGB16 5:6:5"
config VNCSERVER_COLORFMT_RGB32
bool "RGB24 (32-bit) or RGB32 (w/tranparency)"
endchoice # VNC color format
config VNCSERVER_SCREENWIDTH
int "Framebuffer width (pixels)"
default 320
config VNCSERVER_SCREENHEIGHT
int "Framebuffer height (rows)"
default 240
config VNCSERVER_NUPDATES
int "Number of pre-allocate update structures"
default 48
---help---
This setting provides the number of pre-allocated update structures
that will be used. Dynamic memory allocations are never made. In
the likely event that we run out of update structures, the graphics
subsystem will pause and wait for the next structures to be released.
Overhead is 12-bytes per update structure.
config VNCSERVER_UPDATE_BUFSIZE
int "Max update buffer size (bytes)"
default 4096
---help---
A single buffer is pre-allocated for rendering updates. This
setting specifies the maximum in bytes of that update buffer. For
example, an update buffers of 32 pixels at 32-bits per pixel and
32-rows would yield a buffer size of 4096.
config VNCSERVER_KBDENCODE
bool "Encode keyboard input"
default n
depends on NXTERM_NXKBDIN
---help---
Use a special encoding of keyboard characters as defined in
include/nuttx/input/kbd_coded.h.
config VNCSERVER_INBUFFER_SIZE
int "Input buffer size
default 80
endif # VNCSERVER
+48
View File
@@ -0,0 +1,48 @@
############################################################################
# graphics/vnc/server/Make.defs
#
# 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.
#
############################################################################
ifeq ($(CONFIG_VNCSERVER),y)
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
endif
DEPPATH += --dep-path vnc/server
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/vnc/server}
VPATH += :vnc/server
endif
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+323
View File
@@ -0,0 +1,323 @@
/****************************************************************************
* graphics/vnc/vnc_negotiate.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 <assert.h>
#include <debug.h>
#include <nuttx/video/fb.h>
#include <nuttx/video/rfb.h>
#include "vnc_server.h"
/****************************************************************************
* Private Data
****************************************************************************/
#if defined(CONFIG_VNCSERVER_PROTO3p3)
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p3;
#elif defined(CONFIG_VNCSERVER_PROTO3p8)
static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8;
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_negotiate
*
* Description:
* Perform the VNC initialization sequence after the client has sucessfully
* connected to the server. Negotiate security, framebuffer and color
* properties.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* Returns zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_VNCSERVER_PROTO3p3
int vnc_negotiate(FAR struct vnc_session_s *session)
{
FAR struct rfb_sectype_s *sectype;
FAR struct rfb_serverinit_s *serverinit;
FAR struct rfb_pixelfmt_s *pixelfmt;
FAR struct rfb_setpixelformat_s *setformat;
ssize_t nsent;
ssize_t nrecvd;
size_t len;
int errcode;
/* Inform the client of the VNC protocol version */
len = strlen(g_vncproto);
nsent = psock_send(&session->connect, g_vncproto, len, 0);
if (nsent < 0)
{
errcode = get_errno();
gdbg("ERROR: Send ProtocolVersion failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nsent == len);
/* Receive the echo of the protocol string */
nrecvd = psock_recv(&session->connect, session->inbuf, len, 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive protocol confirmation failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nrecvd == len);
/* Tell the client that we won't use any stinkin' security.
*
* "Version 3.3 The server decides the security type and sends a single
* word:"
*/
sectype = (FAR struct rfb_sectype_s *)session->outbuf;
rfb_putbe32(sectype->type, RFB_SECTYPE_NONE);
nsent = psock_send(&session->connect, sectype,
sizeof(struct rfb_sectype_s), 0);
if (nsent < 0)
{
errcode = get_errno();
gdbg("ERROR: Send Security failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nsent == sizeof(struct rfb_sectype_s));
/* Receive the ClientInit message
*
* "Once the client and server are sure that theyre happy to talk to one
* another using the agreed security type, the protocol passes to the
* initialisation phase. The client sends a ClientInit message followed
* by the server sending a ServerInit message."
*
* In this implementation, the sharing flag is ignored.
*/
nrecvd = psock_recv(&session->connect, session->inbuf,
sizeof(struct rfb_clientinit_s), 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive ClientInit failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nrecvd == sizeof(struct rfb_clientinit_s));
/* Send the ClientInit message
*
* "After receiving the ClientInit message, the server sends a ServerInit
* message. This tells the client the width and height of the servers
* framebuffer, its pixel format and the name associated with the desktop:
*/
serverinit = (FAR struct rfb_serverinit_s *)session->outbuf;
rfb_putbe16(serverinit->width, CONFIG_VNCSERVER_SCREENWIDTH);
rfb_putbe16(serverinit->height, CONFIG_VNCSERVER_SCREENHEIGHT);
rfb_putbe32(serverinit->namelen, 0);
pixelfmt = &serverinit->format;
pixelfmt->bpp = RFB_BITSPERPIXEL;
pixelfmt->depth = RFB_PIXELDEPTH;
pixelfmt->bigendian = 0;
pixelfmt->truecolor = RFB_TRUECOLOR;
rfb_putbe16(pixelfmt->rmax, RFB_RMAX);
rfb_putbe16(pixelfmt->gmax, RFB_GMAX);
rfb_putbe16(pixelfmt->bmax, RFB_BMAX);
pixelfmt->rshift = RFB_RSHIFT;
pixelfmt->gshift = RFB_GSHIFT;
pixelfmt->bshift = RFB_BSHIFT;
nsent = psock_send(&session->connect, serverinit,
SIZEOF_RFB_SERVERINIT_S(0), 0);
if (nsent < 0)
{
errcode = get_errno();
gdbg("ERROR: Send ServerInit failed: %d\n", errcode);
return -errcode;
}
DEBUGASSERT(nsent == SIZEOF_RFB_SERVERINIT_S(0));
/* We now expect to receive the SetPixelFormat message from the client.
* This may override some of our framebuffer settings.
*/
setformat = (FAR struct rfb_setpixelformat_s *)session->inbuf;
nrecvd = psock_recv(&session->connect, setformat,
sizeof(struct rfb_setpixelformat_s), 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive SetFormat failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
else if (nrecvd != sizeof(struct rfb_setpixelformat_s))
{
/* Must not be a SetPixelFormat message? */
gdbg("ERROR: SetFormat wrong size: %d\n", (int)nrecvd);
return -EPROTO;
}
else if (setformat->msgtype != RFB_SETPIXELFMT_MSG)
{
gdbg("ERROR: Not a SetFormat message: %d\n", (int)setformat->type);
return -EPROTO;
}
/* Check if the client request format is one that we can handle. */
pixelfmt = &setformat->format;
if (pixelfmt->truecolor == 0)
{
/* At present, we support only TrueColor formats */
gdbg("ERROR: No support for palette colors\n");
return -ENOSYS;
}
if (pixelfmt->bpp == 16 && pixelfmt->depth == 15)
{
session->colorfmt = FB_FMT_RGB16_555;
session->bpp = 16;
}
else if (pixelfmt->bpp == 16 && pixelfmt->depth == 16)
{
session->colorfmt = FB_FMT_RGB16_565;
session->bpp = 16;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 24)
{
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 32)
{
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
}
else
{
/* We do not support any other conversions */
gdbg("ERROR: No support for this BPP=%d and depth=%d\n",
pixelfmt->bpp, pixelfmt->depth);
return -ENOSYS;
}
/* Receive supported encoding types from client, but ignore them.
* we will do only raw format.
*/
(void)psock_recv(&session->connect, session->inbuf,
CONFIG_VNCSERVER_INBUFFER_SIZE, 0);
session->state = VNCSERVER_CONFIGURED;
return OK;
}
#endif
#ifdef CONFIG_VNCSERVER_PROTO3p8
int vnc_negotiate(FAR struct vnc_session_s *session)
{
ssize_t nsent;
ssize_t nrecvd;
size_t len;
/* Inform the client of the VNC protocol version */
len = strlen(g_vncproto);
nsent = psock_send(&session->connect, g_vncproto, len, 0);
if (nsent < 0)
{
errcode = get_errno();
gdbg("ERROR: Send ProtocolVersion failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nsent == len);
/* Receive the echo of the protocol string */
nrecvd = psock_recv(&session->connect, session->inbuf, len, 0);
if (nrecvd <= 0)
{
errcode = get_errno();
gdbg("ERROR: Receive protocol confirmation failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nrecvd == len);
/* Offer the client a choice of security -- where None is the only option. */
#warning Missing logic
return OK;
}
#endif
+369
View File
@@ -0,0 +1,369 @@
/****************************************************************************
* 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 <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/net/net.h>
#include <nuttx/video/rfb.h>
#include "vnc_server.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_read_remainder
*
* Description:
* After receiving the first byte of a client-to-server message, this
* reads in the remainder of the message.
*
* Input Parameters:
* session - An instance of the session structure.
* msglen - The full length of the message
*
* Returned Value:
* At present, always returns OK
*
****************************************************************************/
int vnc_read_remainder(FAR struct vnc_session_s *session, size_t msglen,
size_t offset)
{
ssize_t nrecvd;
size_t ntotal;
int errcode;
/* Loop until the rest of the message is recieved. */
for (ntotal = 0; ntotal < msglen; offset += nrecvd, ntotal += nrecvd)
{
/* Receive more of the message */
nrecvd = psock_recv(&session->connect, &session->inbuf[offset],
msglen - ntotal, 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive message failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
}
return OK;
}
/****************************************************************************
* 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)
{
ssize_t nrecvd;
int errcode;
int ret;
/* Loop until the client disconnects or an unhandled error occurs */
for (; ; )
{
/* Set up to read one byte which should be the message type of the
* next Client-to-Server message. We will block here until the message
* is received.
*/
nrecvd = psock_recv(&session->connect, session->inbuf, 1, 0);
if (nrecvd < 0)
{
errcode = get_errno();
gdbg("ERROR: Receive byte failed: %d\n", errcode);
DEBUGASSERT(errcode > 0);
return -errcode;
}
DEBUGASSERT(nrecvd == 1);
/* The single byte received should be the message type. Handle the
* message according to this message type.
*/
switch (session->inbuf[0])
{
case RFB_SETPIXELFMT_MSG: /* SetPixelFormat */
{
/* Read the rest of the SetPixelFormat message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_setpixelformat_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read SetPixelFormat message: %d\n",
ret);
}
else
{
#warning Missing logic
}
}
break;
case RFB_SETENCODINGS_MSG: /* SetEncodings */
{
FAR struct rfb_setencodings_s *encodings;
uint32_t nencodings;
/* Read the SetEncodings message without the following
* encodings.
*/
ret = vnc_read_remainder(session,
SIZEOF_RFB_SERVERINIT_S(0) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read SetEncodings message: %d\n",
ret);
}
else
{
/* Read the following encodings */
encodings = (FAR struct rfb_setencodings_s *)session->inbuf;
nencodings = rfb_getbe32(encodings->nencodings);
ret = vnc_read_remainder(session,
nencodings * sizeof(uint32_t),
SIZEOF_RFB_SERVERINIT_S(0));
if (ret < 0)
{
gdbg("ERROR: Failed to read encodings: %d\n",
ret);
}
else
{
#warning Missing logic
}
}
}
break;
case RFB_FBUPDATEREQ_MSG: /* FramebufferUpdateRequest */
{
FAR struct rfb_fbupdatereq_s *update;
struct nxgl_rect_s rect;
/* Read the rest of the SetPixelFormat message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_fbupdatereq_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read FramebufferUpdateRequest message: %d\n",
ret);
}
else
{
/* Enqueue the update */
update = (FAR struct rfb_fbupdatereq_s *)session->inbuf;
rect.pt1.x = rfb_getbe16(update->xpos);
rect.pt1.y = rfb_getbe16(update->ypos);
rect.pt2.x = rect.pt1.x + rfb_getbe16(update->width);
rect.pt2.y = rect.pt1.y + rfb_getbe16(update->height);
ret = vnc_update_rectangle(session, &rect);
if (ret < 0)
{
gdbg("ERROR: Failed to queue update: %d\n", ret);
}
}
}
break;
case RFB_KEYEVENT_MSG: /* KeyEvent */
{
FAR struct rfb_keyevent_s *keyevent;
/* Read the rest of the KeyEvent message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_keyevent_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read KeyEvent message: %d\n",
ret);
}
else
{
/* Inject the key press/release event into NX */
keyevent = (FAR struct rfb_keyevent_s *)session->inbuf;
vnc_key_map(session, rfb_getbe16(keyevent->key),
(bool)keyevent->down);
}
}
break;
case RFB_POINTEREVENT_MSG: /* PointerEvent */
{
#ifdef CONFIG_NX_XYINPUT
FAR struct rfb_pointerevent_s *event;
uint8_t buttons;
#endif
/* Read the rest of the PointerEvent message */
ret = vnc_read_remainder(session,
sizeof(struct rfb_pointerevent_s) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read PointerEvent message: %d\n",
ret);
}
#ifdef CONFIG_NX_XYINPUT
else
{
event = (FAR struct rfb_pointerevent_s *)session->inbuf;
/* Map buttons bitmap. Bits 0-7 are buttons 1-8, 0=up,
* 1=down. By convention Bit 0 = left button, Bit 1 =
* middle button, and Bit 2 = right button.
*/
buttons = 0;
if ((event->buttons & (1 << 0)) != 0)
{
buttons |= NX_MOUSE_LEFTBUTTON;
}
if ((event->buttons & (1 << 1)) != 0)
{
buttons |= NX_MOUSE_CENTERBUTTON;
}
if ((event->buttons & (1 << 2)) != 0)
{
buttons |= NX_MOUSE_RIGHTBUTTON;
}
ret = nx_mousein(session->handle,
(nxgl_coord_t)rfb_getbe16(event->xpos),
(nxgl_coord_t)rfb_getbe16(event->ypos),
buttons);
if (ret < 0)
{
gdbg("ERROR: nx_mousein failed: %d\n", ret);
}
}
#endif
}
break;
case RFB_CLIENTCUTTEXT_MSG: /* ClientCutText */
{
FAR struct rfb_clientcuttext_s *cuttext;
uint32_t length;
/* Read the ClientCutText message without the following
* text.
*/
ret = vnc_read_remainder(session,
SIZEOF_RFB_CLIENTCUTTEXT_S(0) - 1,
1);
if (ret < 0)
{
gdbg("ERROR: Failed to read ClientCutText message: %d\n",
ret);
}
else
{
/* Read the following text */
cuttext = (FAR struct rfb_clientcuttext_s *)session->inbuf;
length = rfb_getbe32(cuttext->length);
ret = vnc_read_remainder(session, length,
SIZEOF_RFB_CLIENTCUTTEXT_S(0));
if (ret < 0)
{
gdbg("ERROR: Failed to read text: %d\n",
ret);
}
else
{
#warning Missing logic
}
}
}
break;
default:
gdbg("ERROR: Unsynchronized, msgtype=%d\n", session->inbuf[0]);
return -EPROTO;
}
}
return -ENOSYS;
}
+368
View File
@@ -0,0 +1,368 @@
/****************************************************************************
* graphics/vnc/vnc_server.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 <stdlib.h>
#include <semaphore.h>
#include <string.h>
#include <queue.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <nuttx/kmalloc.h>
#include <nuttx/semaphore.h>
#include <nuttx/net/net.h>
#include "vnc_server.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/* Given a display number as an index, the following array can be used to
* look-up the session structure for that display.
*/
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)
{
FAR struct vnc_fbupdate_s *curr;
FAR struct vnc_fbupdate_s *next;
int i;
/* Close any open sockets */
if (session->state >= VNCSERVER_CONNECTED)
{
psock_close(&session->connect);
psock_close(&session->listen);
}
/* [Re-]initialize the session. */
/* Put all of the pre-allocated update structures into the freelist */
sq_init(&session->updqueue);
session->updfree.head =
(FAR sq_entry_t *)&session->updpool[0];
session->updfree.tail =
(FAR sq_entry_t *)&session->updpool[CONFIG_VNCSERVER_NUPDATES-1];
next = &session->updpool[0];
for (i = 1; i < CONFIG_VNCSERVER_NUPDATES-1; i++)
{
curr = next;
next = &session->updpool[i];
curr->flink = next;
}
next->flink = NULL;
/* Set the INITIALIZED state */
sem_reset(&session->freesem, CONFIG_VNCSERVER_NUPDATES);
sem_reset(&session->queuesem, 0);
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
****************************************************************************/
/****************************************************************************
* Name: vnc_server
*
* Description:
* The VNC server daemon. This daemon is implemented as a kernel thread.
*
* Input Parameters:
* Standard kernel thread arguments (all ignored)
*
* Returned Value:
* This function does not return.
*
****************************************************************************/
int vnc_server(int argc, FAR char *argv[])
{
FAR struct vnc_session_s *session;
FAR uint8_t *fb;
int display;
int ret;
DEBUGASSERT(session != NULL);
/* A single argument is expected: A diplay port number in ASCII form */
if (argc != 2)
{
gdbg("ERROR: Unexpected number of arguments: %d\n", argc);
return EXIT_FAILURE;
}
display = atoi(argv[1]);
if (display < 0 || display >= RFB_MAX_DISPLAYS)
{
gdbg("ERROR: Invalid display number: %d\n", display);
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 = kmm_zalloc(sizeof(struct vnc_session_s));
if (session == NULL)
{
gdbg("ERROR: Failed to allocate session\n");
goto errout_with_fb;
}
g_vnc_sessions[display] = session;
sem_init(&session->freesem, 0, CONFIG_VNCSERVER_NUPDATES);
sem_init(&session->queuesem, 0, 0);
/* Loop... handling each each VNC client connection to this display. Only
* a single client is allowed for each display.
*/
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));
if (ret >= 0)
{
gvdbg("New VNC connection\n");
/* Perform the VNC initialization sequence after the client has
* sucessfully connected to the server. Negotiate security,
* framebuffer and color properties.
*/
ret = vnc_negotiate(session);
if (ret < 0)
{
gdbg("ERROR: Failed to negotiate security/framebuffer: %d\n",
ret);
continue;
}
/* 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);
}
}
}
errout_with_fb:
kmm_free(fb);
return EXIT_FAILURE;
}
/****************************************************************************
* 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)
{
FAR struct vnc_session_s *session = NULL;
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
if (display >= 0 && display < RFB_MAX_DISPLAYS)
{
session = g_vnc_sessions[display];
}
return session;
}
+392
View File
@@ -0,0 +1,392 @@
/****************************************************************************
* graphics/vnc/server/vnc_server.h
*
* 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.
*
****************************************************************************/
#ifndef __GRAPHICS_VNC_SERVER_VNC_SERVER_H
#define __GRAPHICS_VNC_SERVER_VNC_SERVER_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <semaphore.h>
#include <pthread.h>
#include <queue.h>
#include <nuttx/video/fb.h>
#include <nuttx/video/rfb.h>
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nx.h>
#include <nuttx/net/net.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration */
#ifndef CONFIG_NET_TCP_READAHEAD
# error CONFIG_NET_TCP_READAHEAD must be set to use VNC
#endif
#ifndef CONFIG_NX_UPDATE
# error CONFIG_NX_UPDATE must be set to use VNC
#endif
#if !defined(CONFIG_VNCSERVER_PROTO3p3) && !defined(CONFIG_VNCSERVER_PROTO3p8)
# error No VNC protocol selected
#endif
#if defined(CONFIG_VNCSERVER_PROTO3p3) && defined(CONFIG_VNCSERVER_PROTO3p8)
# error Too many VNC protocols selected
#endif
#ifndef CONFIG_VNCSERVER_NDISPLAYS
# define CONFIG_VNCSERVER_NDISPLAYS 1
#endif
#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16)
# define RFB_COLORFMT FB_FMT_RGB16_565
# define RFB_BITSPERPIXEL 16
# define RFB_PIXELDEPTH 16
# define RFB_TRUECOLOR 1
# define RFB_RMAX 0x1f
# define RFB_GMAX 0x3f
# define RFB_BMAX 0x1f
# define RFB_RSHIFT 11
# define RFB_GSHIFT 5
# define RFB_BSHIFT 0
#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32)
# define RFB_COLORFMT FB_FMT_RGB32
# define RFB_BITSPERPIXEL 32
# define RFB_PIXELDEPTH 24
# define RFB_TRUECOLOR 1
# define RFB_RMAX 0xff
# define RFB_GMAX 0xff
# define RFB_BMAX 0xff
# define RFB_RSHIFT 16
# define RFB_GSHIFT 8
# define RFB_BSHIFT 0
#else
# error Unspecified/unsupported color format
#endif
#ifndef CONFIG_VNCSERVER_SCREENWIDTH
# define CONFIG_VNCSERVER_SCREENWIDTH 320
#endif
#ifndef CONFIG_VNCSERVER_SCREENHEIGHT
# define CONFIG_VNCSERVER_SCREENHEIGHT 240
#endif
#ifndef CONFIG_VNCSERVER_PRIO
# define CONFIG_VNCSERVER_PRIO 100
#endif
#ifndef CONFIG_VNCSERVER_STACKSIZE
# 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_INBUFFER_SIZE
# define CONFIG_VNCSERVER_INBUFFER_SIZE 80
#endif
#ifndef CONFIG_VNCSERVER_NUPDATES
# define CONFIG_VNCSERVER_NUPDATES 48
#endif
#ifndef CONFIG_VNCSERVER_UPDATE_BUFSIZE
# define CONFIG_VNCSERVER_UPDATE_BUFSIZE 4096
#endif
#define VNCSERVER_UPDATE_BUFSIZE \
(CONFIG_VNCSERVER_UPDATE_BUFSIZE + SIZEOF_RFB_FRAMEBUFFERUPDATE_S(0))
/* 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
#define RFB_MAX_DISPLAYS CONFIG_VNCSERVER_NDISPLAYS
#define RFB_DISPLAY_PORT(d) (RFB_PORT_BASE + (d))
/* Miscellaneous */
#ifndef MIN
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* This enumeration indicates the state of the VNC server */
enum vnc_server_e
{
VNCSERVER_UNINITIALIZED = 0, /* Initial state */
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_RUNNING, /* Running and activly transferring graphics */
VNCSERVER_STOPPING, /* The updater has been asked to stop */
VNCSERVER_STOPPED /* The updater has stopped */
};
/* This structure is used to queue FrameBufferUpdate event. It includes a
* pointer to support singly linked list.
*/
struct vnc_fbupdate_s
{
FAR struct vnc_fbupdate_s *flink;
struct nxgl_rect_s rect; /* The enqueued update rectangle */
};
struct vnc_session_s
{
/* NX graphics system */
NXHANDLE handle; /* NX graphics handle */
/* Connection data */
struct socket listen; /* Listen socket */
struct socket connect; /* Connected socket */
volatile uint8_t state; /* See enum vnc_server_e */
/* Display geometry and color characteristics */
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 */
/* Updater information */
pthread_t updater; /* Updater thread ID */
/* Update list information */
struct vnc_fbupdate_s updpool[CONFIG_VNCSERVER_NUPDATES];
sq_queue_t updfree;
sq_queue_t updqueue;
sem_t freesem;
sem_t queuesem;
/* I/O buffers for misc network send/receive */
uint8_t inbuf[CONFIG_VNCSERVER_INBUFFER_SIZE];
uint8_t outbuf[VNCSERVER_UPDATE_BUFSIZE];
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Name: vnc_server
*
* Description:
* The VNC server daemon. This daemon is implemented as a kernel thread.
*
* Input Parameters:
* Standard kernel thread arguments (all ignored)
*
* Returned Value:
* This function does not return.
*
****************************************************************************/
int vnc_server(int argc, FAR char *argv[]);
/****************************************************************************
* Name: vnc_negotiate
*
* Description:
* Perform the VNC initialization sequence after the client has sucessfully
* connected to the server. Negotiate security, framebuffer and color
* properties.
*
* Input Parameters:
* session - An instance of the session structure.
*
* Returned Value:
* Returns zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
int vnc_negotiate(FAR struct vnc_session_s *session);
/****************************************************************************
* 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);
/****************************************************************************
* 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_update_rectangle
*
* Description:
* Queue an update of the specified rectangular region on the display.
*
* Input Parameters:
* session - An instance of the session structure.
* rect - The rectanglular region to be updated.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
int vnc_update_rectangle(FAR struct vnc_session_s *session,
FAR const struct nxgl_rect_s *rect);
/****************************************************************************
* 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);
/****************************************************************************
* Name: vnc_key_map
*
* Description:
* Map the receive X11 keysym into something understood by NuttX and route
* that through NX to the appropriate window.
*
* Input Parameters:
* session - An instance of the session structure.
* keysym - The X11 keysym value (see include/nuttx/inputx11_keysymdef)
* keydown - True: Key pressed; False: Key released
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_KBD
void vnc_key_map(FAR struct vnc_session_s *session, uint16_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
}
#endif
#endif /* __GRAPHICS_VNC_SERVER_VNC_SERVER_H */
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -261,7 +261,7 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev,
size_t recvlen = recvfrom_newdata(dev, pstate);
/* If there is more data left in the packet that we could not buffer, than
/* If there is more data left in the packet that we could not buffer, then
* add it to the read-ahead buffers.
*/