mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
Merge branch 'vnc'
This commit is contained in:
@@ -745,4 +745,7 @@ config NXSTART_VPLANE
|
|||||||
|
|
||||||
endif # NX_NXSTART
|
endif # NX_NXSTART
|
||||||
endif # NX_MULTIUSER
|
endif # NX_MULTIUSER
|
||||||
|
|
||||||
|
source "graphics/vnc/Kconfig"
|
||||||
|
|
||||||
endif # NX
|
endif # NX
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ include nxbe/Make.defs
|
|||||||
include nxmu/Make.defs
|
include nxmu/Make.defs
|
||||||
include nxsu/Make.defs
|
include nxsu/Make.defs
|
||||||
include nxterm/Make.defs
|
include nxterm/Make.defs
|
||||||
|
include vnc/Make.defs
|
||||||
|
|
||||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||||
|
|||||||
@@ -112,6 +112,10 @@ nuttx/../NxWidgets
|
|||||||
The NxWidgets code is provided as a separate package located outside of the
|
The NxWidgets code is provided as a separate package located outside of the
|
||||||
NuttX source tree (probably at this location).
|
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
|
Installing New Fonts
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@@ -295,6 +299,8 @@ CONFIG_NXTK_AUTORAISE
|
|||||||
CONFIG_NXFONTS_CHARBITS
|
CONFIG_NXFONTS_CHARBITS
|
||||||
The number of bits in the character set. Current options are only 7 and 8.
|
The number of bits in the character set. Current options are only 7 and 8.
|
||||||
The default is 7.
|
The default is 7.
|
||||||
|
CONFIG_VNCSERVER and CONFIG_VNCCLIENT
|
||||||
|
Enable the VNC RFB server and client, respecitively.
|
||||||
|
|
||||||
Font Selections
|
Font Selections
|
||||||
---------------
|
---------------
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
@@ -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 they’re 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 server’s
|
||||||
|
* 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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
@@ -261,7 +261,7 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
size_t recvlen = recvfrom_newdata(dev, pstate);
|
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.
|
* add it to the read-ahead buffers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user