Merged nuttx/nuttx into master

This commit is contained in:
ziggurat29 2016-04-23 12:12:30 -05:00
commit 0b8f953f49
24 changed files with 3161 additions and 307 deletions

View File

@ -11376,7 +11376,7 @@
I2C_READ and I2C_WRITE which are not thread safe (2016-01-26).
* SPI: Rename the STM32 up_spiinitialize() to stm32_spibus_initialize()
(2016-01-26).
* SPI: Rename the SAM up_spiinitialize() to stm32_spibus_initialize()
* SPI: Rename the SAM up_spiinitialize() to sam_spibus_initialize()
(2016-01-26).
* SPI: Rename the Tiva up_spiinitialize() to tiva_spibus_intialize()
(2016-01-26).
@ -11665,4 +11665,13 @@
complete, but untested and so not ready for primetime (2016-04-18).
* configs/samv71-xult/vnc: Add a configuration that will be used to
verify VNC (also untested) (2016-04-18).
* drivers/ioexpander: Fix an error in the PCA9555 driver: Under certain
error conditions, interrupts were not being re-enabled. Sebastien
Lorquet (2016-04-20).
* arch/arm/src/stm32 and configs/stm32f429i-disco: Correct some bad
commits that broke the LTDC display example. From Marco Krahl
(2016-04-22).
* configs/samv71-xult/vnwwm: Add a more complex NxWM configuration
to support further VNC testing (particularly of VNC keyboard and
mouse intputs). Initial configuration is not functional (2016-04-23).

View File

@ -329,11 +329,21 @@
# define GPIO_FSMC_NCE4_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN11)
# define GPIO_FSMC_NIORD (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN6)
# define GPIO_FSMC_NIOWR (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN8)
# define GPIO_FSMC_SDCKE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN2)
# define GPIO_FSMC_SDCKE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN3)
# define GPIO_FSMC_SDNE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN3)
# define GPIO_FSMC_SDNE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN2)
# define GPIO_FSMC_SDNWE_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN0)
# define GPIO_FSMC_SDNWE_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTH|GPIO_PIN5)
# define GPIO_FSMC_SDNRAS (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN11)
# define GPIO_FSMC_SDCLK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN8)
# define GPIO_FSMC_SDNCAS (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN15)
# define GPIO_FSMC_BA0 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN4)
# define GPIO_FSMC_BA1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTG|GPIO_PIN5)
# define GPIO_FSMC_NREG (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTF|GPIO_PIN7)
#endif
#if defined(CONFIG_STM32_STM32F427) || defined(CONFIG_STM32_STM32F429) || \
defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469)
#if defined(CONFIG_STM32_STM32F446) || defined(CONFIG_STM32_STM32F469)
# define GPIO_FSMC_SDCKE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN3)
# define GPIO_FSMC_SDCKE0_2 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN5)
# define GPIO_FSMC_SDNE0_1 (GPIO_ALT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PORTC|GPIO_PIN2)

View File

@ -2206,25 +2206,25 @@ Configuration sub-directories
The NxWM window manager can be found here:
nuttx-git/NxWidgets/nxwm
NxWidgets/nxwm
The NxWM unit test can be found at:
nuttx-git/NxWidgets/UnitTests/nxwm
NxWidgets/UnitTests/nxwm
Documentation for installing the NxWM unit test can be found here:
nuttx-git/NxWidgets/UnitTests/README.txt
NxWidgets/UnitTests/README.txt
2. Here is the quick summary of the build steps. These steps assume
that you have the entire NuttX GIT in some directory ~/nuttx-git.
You may have these components installed elsewhere. In that case, you
that you have the entire NuttX GIT in some directory HOME. You may
have these components installed elsewhere. In that case, you
will need to adjust all of the paths in the following accordingly:
a. Install the nxwm configuration
a. Install the VNC nxwm configuration
$ cd ~/nuttx-git/nuttx/tools
$ ./configure.sh samv71-xult/nxwm
$ cd HOME/nuttx/tools
$ ./configure.sh samv71-xult/vnc
b. Make the build context (only)
@ -2241,27 +2241,27 @@ Configuration sub-directories
c. Install the nxwm unit test
$ cd ~/nuttx-git/NxWidgets
$ tools/install.sh ~/nuttx-git/apps nxwm
$ cd HOME/NxWidgets
$ tools/install.sh HOME/apps nxwm
Creating symbolic link
- To ~/nuttx-git/NxWidgets/UnitTests/nxwm
- At ~/nuttx-git/apps/external
- To HOME/NxWidgets/UnitTests/nxwm
- At HOME/apps/external
d. Build the NxWidgets library
$ cd ~/nuttx-git/NxWidgets/libnxwidgets
$ make TOPDIR=~/nuttx-git/nuttx
$ cd HOME/NxWidgets/libnxwidgets
$ make TOPDIR=HOME/nuttx
...
e. Build the NxWM library
$ cd ~/nuttx-git/NxWidgets/nxwm
$ make TOPDIR=~/nuttx-git/nuttx
$ cd HOME/NxWidgets/nxwm
$ make TOPDIR=HOME/nuttx
...
f. Built NuttX with the installed unit test as the application
$ cd ~/nuttx-git/nuttx
$ cd HOME/nuttx
$ make
3. Reading from the LCD is not currently functional. The following
@ -2320,7 +2320,7 @@ Configuration sub-directories
1. Network configuration: IP address 10.0.0.2. The is easily changed
via 'make menuconfig'. The VNC server address is 10.0.0.2:5900.
2. The default (local) framebuffer configuration is 320x240 with 16-bit
2. The default (local) framebuffer configuration is 320x240 with 8-bit
RGB color.
3. There are complicated interactions between VNC and the network
@ -2328,7 +2328,7 @@ Configuration sub-directories
size of update messages. That is 1024 bytes in that configuration
(the full message with the header will be a little larger). The
MTU (CONFIG_NET_ETH_MTU) is set to 590 so that a full update will
require several packets.i
require several packets.
Write buffering also effects network performance. This will break
up the large updates into small (196 byte) groups. When we run out
@ -2339,3 +2339,166 @@ Configuration sub-directories
mouse/keyboard inputs in the options/input menu. That will make
things a little clearer.
5. To select 16-bits per pixel RGB15 5:6:5
CONFIG_NX_DISABLE_8BPP=y
# CONFIG_NX_DISABLE_16BPP is not set
# CONFIG_VNCSERVER_COLORFMT_RGB8 is not set
CONFIG_VNCSERVER_COLORFMT_RGB16=y
CONFIG_EXAMPLES_NXIMAGE_BPP=16
To re-select 8-bits per pixel RGB8 3:3:2
# CONFIG_NX_DISABLE_8BPP is not set
CONFIG_NX_DISABLE_16BPP=y
CONFIG_VNCSERVER_COLORFMT_RGB8=y
# CONFIG_VNCSERVER_COLORFMT_RGB16 is not set
# CONFIG_EXAMPLES_NXIMAGE_GREYSCALE is not set
CONFIG_EXAMPLES_NXIMAGE_BPP=8
STATUS:
2016-04-21: I have gotten the apps/examples/nximage to work with
lots issues with 16-bit RGB and verbose GRAPHICS and UPDATER debug
ON. There are reliability problems and it hangs at the end of the
test.
2016-04-22: The default configuration now uses RGB8 which needs a lot
less SRAM for the local frame buffer and does not degrade the color
quality in the remote display (since it is also 8 BPP). At 8
BPP, the remote display is correct even with both GRAPHICS and
UPDATER debug OFF -- and there is no hang!
2106-04-23: The NxImage test was selected because it is a very simple
graphics test. Continued testing, however, requires a more complex
configuration. Hence, the vnxwm configuration was created.
A memory clobber error was fixed and this probably corrects some of
the reliability problems noted on 2016-04-21.
vnxwm:
This is a special configuration setup for the NxWM window manager
UnitTest. It provides an interactive windowing experience via a remote
VNC client window running on your PC. The SAMV71-XULT is connected to
the PC via Ethernet.
NOTES:
1. The NxWM window manager is a tiny window manager tailored for use
with smaller LCDs. It supports a task, a start window, and
multiple application windows with toolbars. However, to make the
best use of the visible LCD space, only one application window is
visible at at time.
The NxWM window manager can be found here:
NxWidgets/nxwm
The NxWM unit test can be found at:
NxWidgets/UnitTests/nxwm
Documentation for installing the NxWM unit test can be found here:
NxWidgets/UnitTests/README.txt
2. Here is the quick summary of the build steps. These steps assume
that you have the entire NuttX GIT in some directory HOME. You may
have these components installed elsewhere. In that case, you
will need to adjust all of the paths in the following accordingly:
a. Install the nxwm configuration
$ cd HOME/nuttx/tools
$ ./configure.sh samv71-xult/nxwm
b. Make the build context (only)
$ cd ..
$ . ./setenv.sh
$ make context
...
NOTE: the use of the setenv.sh file is optional. All that it will
do is to adjust your PATH variable so that the build system can find
your tools. If you use it, you will most likely need to modify the
script so that it has the correct path to your tool binaries
directory.
c. Install the nxwm unit test
$ cd HOME/NxWidgets
$ tools/install.sh HOME/apps nxwm
Creating symbolic link
- To HOME/NxWidgets/UnitTests/nxwm
- At HOME/apps/external
d. Build the NxWidgets library
$ cd HOME/NxWidgets/libnxwidgets
$ make TOPDIR=HOME/nuttx
...
e. Build the NxWM library
$ cd HOME/NxWidgets/nxwm
$ make TOPDIR=HOME/nuttx
...
f. Built NuttX with the installed unit test as the application
$ cd HOME/nuttx
$ make
3. Network configuration: IP address 10.0.0.2. The is easily changed
via 'make menuconfig'. The VNC server address is 10.0.0.2:5900.
4. The default (local) framebuffer configuration is 320x240 with 8-bit
RGB color.
I had some problems at 16-bits per pixle (see STATUS below). To
select 16-bits per pixel RGB15 5:6:5
CONFIG_NX_DISABLE_8BPP=y
# CONFIG_NX_DISABLE_16BPP is not set
# CONFIG_VNCSERVER_COLORFMT_RGB8 is not set
CONFIG_VNCSERVER_COLORFMT_RGB16=y
CONFIG_EXAMPLES_NXIMAGE_BPP=16
To re-select 8-bits per pixel RGB8 3:3:2
# CONFIG_NX_DISABLE_8BPP is not set
CONFIG_NX_DISABLE_16BPP=y
CONFIG_VNCSERVER_COLORFMT_RGB8=y
# CONFIG_VNCSERVER_COLORFMT_RGB16 is not set
# CONFIG_EXAMPLES_NXIMAGE_GREYSCALE is not set
CONFIG_EXAMPLES_NXIMAGE_BPP=8
5. There are complicated interactions between VNC and the network
configuration. The CONFIG_VNCSERVER_UPDATE_BUFSIZE determines the
size of update messages. That is 1024 bytes in that configuration
(the full message with the header will be a little larger). The
MTU (CONFIG_NET_ETH_MTU) is set to 590 so that a full update will
require several packets.
Write buffering also effects network performance. This will break
up the large updates into small (196 byte) groups. When we run out
of read-ahead buffers, then partial updates may be sent causing a
loss of synchronization.
STATUS:
2106-04-23: Configuration created. See status up to this data in
the vnc configuration. That probably all applies here as well.
Only some initial testing has been performed: The configuration
does not work. No crashes or errors are reported, but the VNC
client window stays black. I have not yet dug into this.

View File

@ -832,7 +832,7 @@ CONFIG_NET_IOB=y
CONFIG_IOB_NBUFFERS=72
CONFIG_IOB_BUFSIZE=196
CONFIG_IOB_NCHAINS=8
CONFIG_IOB_THROTTLE=8
CONFIG_IOB_THROTTLE=32
# CONFIG_NET_ARCH_INCR32 is not set
# CONFIG_NET_ARCH_CHKSUM is not set
CONFIG_NET_STATISTICS=y
@ -901,20 +901,20 @@ CONFIG_FS_PROCFS=y
CONFIG_NX=y
CONFIG_NX_NPLANES=1
CONFIG_NX_BGCOLOR=0x0
# CONFIG_NX_ANTIALIASING is not set
# CONFIG_NX_WRITEONLY is not set
CONFIG_NX_UPDATE=y
#
# Supported Pixel Depths
#
# CONFIG_NX_DISABLE_1BPP is not set
# CONFIG_NX_DISABLE_2BPP is not set
# CONFIG_NX_DISABLE_4BPP is not set
CONFIG_NX_DISABLE_1BPP=y
CONFIG_NX_DISABLE_2BPP=y
CONFIG_NX_DISABLE_4BPP=y
# CONFIG_NX_DISABLE_8BPP is not set
# CONFIG_NX_DISABLE_16BPP is not set
# CONFIG_NX_DISABLE_24BPP is not set
CONFIG_NX_DISABLE_16BPP=y
CONFIG_NX_DISABLE_24BPP=y
CONFIG_NX_DISABLE_32BPP=y
CONFIG_NX_PACKEDMSFIRST=y
#
# Input Devices
@ -988,11 +988,13 @@ CONFIG_VNCSERVER=y
# CONFIG_VNCSERVER_PROTO3p3 is not set
CONFIG_VNCSERVER_PROTO3p8=y
CONFIG_VNCSERVER_NDISPLAYS=1
CONFIG_VNCSERVER_NAME="NuttX"
CONFIG_VNCSERVER_PRIO=100
CONFIG_VNCSERVER_STACKSIZE=2048
CONFIG_VNCSERVER_UPDATER_PRIO=100
CONFIG_VNCSERVER_UPDATER_STACKSIZE=2048
CONFIG_VNCSERVER_COLORFMT_RGB16=y
CONFIG_VNCSERVER_COLORFMT_RGB8=y
# CONFIG_VNCSERVER_COLORFMT_RGB16 is not set
# CONFIG_VNCSERVER_COLORFMT_RGB32 is not set
CONFIG_VNCSERVER_SCREENWIDTH=320
CONFIG_VNCSERVER_SCREENHEIGHT=240
@ -1126,7 +1128,8 @@ CONFIG_EXAMPLES_NSH=y
CONFIG_EXAMPLES_NXIMAGE=y
CONFIG_EXAMPLES_NXIMAGE_VPLANE=0
CONFIG_EXAMPLES_NXIMAGE_DEVNO=0
CONFIG_EXAMPLES_NXIMAGE_BPP=16
CONFIG_EXAMPLES_NXIMAGE_BPP=8
# CONFIG_EXAMPLES_NXIMAGE_GREYSCALE is not set
# CONFIG_EXAMPLES_NXIMAGE_XSCALEp5 is not set
CONFIG_EXAMPLES_NXIMAGE_XSCALE1p0=y
# CONFIG_EXAMPLES_NXIMAGE_XSCALE1p5 is not set

View File

@ -0,0 +1,117 @@
############################################################################
# configs/samv71-xult/vnxwm/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 ${TOPDIR}/.config
include ${TOPDIR}/tools/Config.mk
include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
ifeq ($(CONFIG_ARMV7M_DTCM),y)
LDSCRIPT = flash-dtcm.ld
else
LDSCRIPT = flash-sram.ld
endif
ifeq ($(WINTOOL),y)
# Windows-native toolchains
DIRLINK = $(TOPDIR)/tools/copydir.sh
DIRUNLINK = $(TOPDIR)/tools/unlink.sh
MKDEP = $(TOPDIR)/tools/mkwindeps.sh
ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
else
# Linux/Cygwin-native toolchain
MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
endif
CC = $(CROSSDEV)gcc
CXX = $(CROSSDEV)g++
CPP = $(CROSSDEV)gcc -E
LD = $(CROSSDEV)ld
AR = $(CROSSDEV)ar rcs
NM = $(CROSSDEV)nm
OBJCOPY = $(CROSSDEV)objcopy
OBJDUMP = $(CROSSDEV)objdump
ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
ARCHOPTIMIZATION = -g
endif
ifneq ($(CONFIG_DEBUG_NOOPT),y)
ARCHOPTIMIZATION += $(MAXOPTIMIZATION)
endif
ARCHCFLAGS = -fno-builtin
ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fno-rtti
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -fno-strict-aliasing
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
ARCHDEFINES =
ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
NXFLATLDFLAGS1 = -r -d -warn-common
NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
LDNXFLATFLAGS = -e main -s 2048
ASMEXT = .S
OBJEXT = .o
LIBEXT = .a
EXEEXT =
ifneq ($(CROSSDEV),arm-nuttx-elf-)
LDFLAGS += -nostartfiles -nodefaultlibs
endif
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
LDFLAGS += -g
endif
HOSTCC = gcc
HOSTINCLUDES = -I.
HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
HOSTLDFLAGS =

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
#!/bin/bash
# configs/samv7-xult/vnxwm/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.
#
if [ "$_" = "$0" ] ; then
echo "You must source this script, not run it!" 1>&2
exit 1
fi
WD=`pwd`
if [ ! -x "setenv.sh" ]; then
echo "This script must be executed from the top-level NuttX build directory"
exit 1
fi
if [ -z "${PATH_ORIG}" ]; then
export PATH_ORIG="${PATH}"
fi
# This is the Cygwin path to the location where I installed the Atmel GCC
# toolchain under Windows. You will also have to edit this if you install
# this toolchain in any other location
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/Atmel/Atmel Toolchain/ARM GCC/Native/4.7.3.99/arm-gnu-toolchain/bin"
# This is the Cygwin path to the location where I installed the CodeSourcery
# toolchain under windows. You will also have to edit this if you install
# the CodeSourcery toolchain in any other location
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin"
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
# export TOOLCHAIN_BIN="/cygdrive/c/Users/MyName/MentorGraphics/Sourcery_CodeBench_Lite_for_ARM_EABI/bin"
# This is the location where I installed the ARM "GNU Tools for ARM Embedded Processors"
# You can this free toolchain here https://launchpad.net/gcc-arm-embedded
export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q2/bin"
# This is the path to the location where I installed the devkitARM toolchain
# You can get this free toolchain from http://devkitpro.org/ or http://sourceforge.net/projects/devkitpro/
#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/devkitARM/bin"
# This is the Cygwin path to the location where I build the buildroot
# toolchain.
# export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin"
# Add the path to the toolchain to the PATH varialble
export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}"
echo "PATH : ${PATH}"

View File

@ -50,6 +50,10 @@
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxglib.h>
#ifdef CONFIG_VNCSERVER
# include <nuttx/video/vnc.h>
#endif
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
@ -130,6 +134,17 @@ int board_tsc_setup(int minor)
goto errout_with_fb;
}
#ifdef CONFIG_VNCSERVER
/* Setup the VNC server to support keyboard/mouse inputs */
ret = vnc_default_fbinitialize(0, g_simtc.hnx);
if (ret < 0)
{
idbg("vnc_default_fbinitialize failed: %d\n", ret);
goto errout_with_fb;
}
#endif
/* Set the background to the configured background color */
ivdbg("Set background color=%d\n", CONFIG_EXAMPLES_TOUCHSCREEN_BGCOLOR);

View File

@ -69,6 +69,10 @@
/* spi frequency based on arch/arm/src/stm32/stm32_spi.c */
#ifndef CONFIG_STM32F429I_DISCO_ILI9341_SPIFREQUENCY
# define CONFIG_STM32F429I_DISCO_ILI9341_SPIFREQUENCY 20000000
#endif
#if CONFIG_STM32F429I_DISCO_ILI9341_SPIFREQUENCY >= \
(STM32_PCLK1_FREQUENCY >> 1)
# define ILI93414WS_SPI_BR SPI_CR1_FPCLCKd2 /* 000: fPCLK/2 */

View File

@ -53,22 +53,6 @@
#ifdef CONFIG_NX_NXSTART
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/

View File

@ -118,13 +118,29 @@ config VNCSERVER_UPDATE_BUFSIZE
config VNCSERVER_KBDENCODE
bool "Encode keyboard input"
default n
depends on NXTERM_NXKBDIN
depends on LIB_KBDCODEC
---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
int "Input buffer size"
default 80
config VNCSERVER_DEBUG
bool "VNC Server debug"
default n
depends on DEBUG && !DEBUG_GRAPHICS
---help---
Normally VNC debug output is selected with DEBUG_GRAPHICS. The VNC
server server suupport this special option to enable GRAPHICS debug
output for the VNC server while GRAPHICS debug is disabled. This
provides an cleaner, less cluttered output when you only wish to
debug the VNC server versus enabling DEBUG_GRAPHICS globally.
config VNCSERVER_UPDATE_DEBUG
bool "Detailed updater debug"
default n
depends on DEBUG_GRAPHICS || VNCSERVER_DEBUG
endif # VNCSERVER

View File

@ -265,9 +265,14 @@ uint32_t vnc_convert_rgb32_888(lfb_color_t rgb)
* Name: vnc_colors
*
* Description:
* Test the update rectangle to see if it contains complex colors. If it
* contains only a few colors, then it may be a candidate for some type
* run-length encoding.
* Test the update rectangle to see if it contains complex colors. If it
* contains only a few colors, then it may be a candidate for some type
* run-length encoding.
*
* REVISIT: This function is imperfect: It will fail if there are more
* than 8 colors in the region. For small colors, we can keep a local
* array for all color formats and always return the exact result, no
* matter now many colors.
*
* Input Parameters:
* session - An instance of the session structure.
@ -280,15 +285,13 @@ uint32_t vnc_convert_rgb32_888(lfb_color_t rgb)
* The number of valid colors in the colors[] array are returned, the
* first entry being the most frequent. A negated errno value is returned
* if the colors cannot be determined. This would be the case if the color
* depth is > 8 and there are more than 'maxcolors' colors in the update
* rectangle.
* there are more than 'maxcolors' colors in the update rectangle.
*
****************************************************************************/
int vnc_colors(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect,
unsigned int maxcolors, FAR lfb_color_t *colors)
{
#if RFB_PIXELDEPTH > 8
FAR const lfb_color_t *rowstart;
FAR const lfb_color_t *pixptr;
lfb_color_t pixel;
@ -412,12 +415,4 @@ int vnc_colors(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect,
/* And return the number of colors that we found */
return ncolors;
#else
/* For small colors, we can keep a local array for all color formats and
* always return the exact result, no matter now many colors. OR we could
* just remove this conditional compilation and live with 8 colors max.
*/
# error No support for small colors
#endif
}

View File

@ -43,11 +43,20 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#include <nuttx/kthread.h>
#include <nuttx/semaphore.h>
#include <nuttx/video/fb.h>
#include <nuttx/video/vnc.h>
#include "vnc_server.h"
@ -158,7 +167,9 @@ static int up_getvideoinfo(FAR struct fb_vtable_s *vtable,
DEBUGASSERT(fbinfo != NULL && vinfo != NULL);
if (fbinfo != NULL && vinfo != NULL)
{
session = vnc_find_session(fbinfo->display);
DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[fbinfo->display];
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
gdbg("ERROR: session is not connected\n");
@ -197,7 +208,9 @@ static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
DEBUGASSERT(fbinfo != NULL && pinfo != NULL && planeno == 0);
if (fbinfo != NULL && pinfo != NULL && planeno == 0)
{
session = vnc_find_session(fbinfo->display);
DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[fbinfo->display];
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
gdbg("ERROR: session is not connected\n");
@ -242,7 +255,9 @@ static int up_getcmap(FAR struct fb_vtable_s *vtable,
if (fbinfo != NULL && cmap != NULL)
{
session = vnc_find_session(fbinfo->display);
DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[fbinfo->display];
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
gdbg("ERROR: session is not connected\n");
@ -277,7 +292,9 @@ static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s
if (fbinfo != NULL && cmap != NULL)
{
session = vnc_find_session(fbinfo->display);
DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[fbinfo->display];
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
gdbg("ERROR: session is not connected\n");
@ -313,7 +330,9 @@ static int up_getcursor(FAR struct fb_vtable_s *vtable,
if (fbinfo != NULL && attrib != NULL)
{
session = vnc_find_session(fbinfo->display);
DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[fbinfo->display];
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
gdbg("ERROR: session is not connected\n");
@ -347,7 +366,9 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable,
if (fbinfo != NULL && settings != NULL)
{
session = vnc_find_session(fbinfo->display);
DEBUGASSERT(fbinfo->display >= 0 && fbinfo->display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[fbinfo->display];
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
gdbg("ERROR: session is not connected\n");
@ -381,7 +402,121 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable,
#endif
/****************************************************************************
* Name: vnc_wait_server
* Name: vnc_start_server
*
* Description:
* Start the VNC server.
*
* Input parameters:
* display - In the case of hardware with multiple displays, this
* specifies the display. Normally this is zero.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
static int vnc_start_server(int display)
{
FAR char *argv[2];
char str[8];
pid_t pid;
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
/* Check if the server is already running */
if (g_vnc_sessions[display] != NULL)
{
DEBUGASSERT(g_vnc_sessions[display]->state >= VNCSERVER_INITIALIZED);
return OK;
}
/* Start the VNC server kernel thread. */
gvdbg("Starting the VNC server for display %d\n", display);
g_fbstartup[display].result = -EBUSY;
sem_reset(&g_fbstartup[display].fbinit, 0);
sem_reset(&g_fbstartup[display].fbconnect, 0);
/* Format the kernel thread arguments (ASCII.. yech) */
(void)itoa(display, str, 10);
argv[0] = str;
argv[1] = NULL;
pid = kernel_thread("vnc_server", CONFIG_VNCSERVER_PRIO,
CONFIG_VNCSERVER_STACKSIZE,
(main_t)vnc_server, argv);
if (pid < 0)
{
gdbg("ERROR: Failed to start the VNC server: %d\n", (int)pid);
return (int)pid;
}
return OK;
}
/****************************************************************************
* Name: vnc_wait_start
*
* Description:
* Wait for the server to be started.
*
* Input parameters:
* display - In the case of hardware with multiple displays, this
* specifies the display. Normally this is zero.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure.
*
****************************************************************************/
static inline int vnc_wait_start(int display)
{
int errcode;
/* Check if there has been a session allocated yet. This is one of the
* first things that the VNC server will do with the kernel thread is
* started. But we might be here before the thread has gotten that far.
*
* If it has been allocated, then wait until it is in the INIITIALIZED
* state. The INITIAILIZED states indicates tht the session structure
* has been allocated and fully initialized.
*/
while (g_vnc_sessions[display] == NULL ||
g_vnc_sessions[display]->state != VNCSERVER_UNINITIALIZED)
{
/* The server is not yet running. Wait for the server to post the FB
* semaphore. In certain error situations, the server may post the
* semaphore, then reset it to zero. There are are certainly race
* conditions here, but I think none that are fatal.
*/
while (sem_wait(&g_fbstartup[display].fbinit) < 0)
{
errcode = get_errno();
/* sem_wait() should fail only if it is interrupt by a signal. */
DEBUGASSERT(errcode == EINTR);
if (errcode != EINTR)
{
DEBUGASSERT(errcode > 0);
return -errcode;
}
}
}
return OK;
}
/****************************************************************************
* Name: vnc_wait_connect
*
* Description:
* Wait for the server to be connected to the VNC client. We can do
@ -397,7 +532,7 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable,
*
****************************************************************************/
static inline int vnc_wait_server(int display)
static inline int vnc_wait_connect(int display)
{
int errcode;
int result;
@ -423,7 +558,7 @@ static inline int vnc_wait_server(int display)
* conditions here, but I think none that are fatal.
*/
while (sem_wait(&g_fbstartup[display].fbsem) < 0)
while (sem_wait(&g_fbstartup[display].fbconnect) < 0)
{
errcode = get_errno();
@ -486,48 +621,119 @@ static inline int vnc_wait_server(int display)
int up_fbinitialize(int display)
{
FAR char *argv[2];
char str[8];
pid_t pid;
int ret;
/* Start the VNC server kernel thread.
* REVISIT: There is no protection for the case where this function is
* called more that once.
*/
gvdbg("Starting the VNC server for display %d\n", display);
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
/* Check if the server is already running */
/* Start the VNC server kernel thread. */
g_fbstartup[display].result = -EBUSY;
sem_reset(&g_fbstartup[display].fbsem, 0);
if (g_vnc_sessions[display] != NULL)
ret = vnc_start_server(display);
if (ret < 0)
{
DEBUGASSERT(g_vnc_sessions[display]->state >= VNCSERVER_INITIALIZED);
}
else
{
/* Format the kernel thread arguments (ASCII.. yech) */
(void)itoa(display, str, 10);
argv[0] = str;
argv[1] = NULL;
pid = kernel_thread("vnc_server", CONFIG_VNCSERVER_PRIO,
CONFIG_VNCSERVER_STACKSIZE,
(main_t)vnc_server, argv);
if (pid < 0)
{
gdbg("ERROR: Failed to start the VNC server: %d\n", (int)pid);
return (int)pid;
}
gvdbg("ERROR: vnc_start_server() failed: %d\n", ret);
return ret;
}
/* Wait for the VNC client to connect and for the RFB to be ready */
return vnc_wait_server(display);
ret = vnc_wait_connect(display);
if (ret < 0)
{
gvdbg("ERROR: vnc_wait_connect() failed: %d\n", ret);
}
return ret;
}
/****************************************************************************
* Function: vnc_fbinitialize
*
* Description:
* Initialize the VNC frame buffer driver. The VNC frame buffer driver
* supports two initialization interfaces: The standard up_fbinitialize()
* that will be called from the graphics layer and this speical
* initialization function that can be used only by VNC aware OS logic.
*
* The two initialization functions may be called separated or together in
* either order. The difference is that standard up_fbinitialize(), if
* used by itself, will not have any remote mouse or keyboard inputs that
* are reported to the VNC framebuffer driver from the remote VNC client.
*
* In the standard graphics architecture, the keyboard/mouse inputs are
* received by some appliation/board specific logic at the highest level
* in the architecture via input drivers. The received keyboard/mouse
* input data must then be "injected" into NX where it can they can be
* assigned to the window that has focus. They will eventually be
* received by the Window instances via NX callback methods.
*
* NX is a middleware layer in the architecture, below the
* application/board specific logic but above the driver level logic. The
* frame buffer driver, on the other hand lies at the very lowest level in
* the graphics architecture. It cannot call upward into the application
* nor can it call upward into NX. So, some other logic.
*
* vnc_fbinitialize() provides an optional, alternative initialization
* function. It is optional becuase it need not be called. If it is not
* called, however, keyboard/mouse inputs from the remote VNC client will
* be lost. By calling vnc_fbinitialize(), you can provide callout
* functions that can be received by logic higher in the architure. This
* higher level level callouts can then call nx_kbdin() or nx_mousein() on
* behalf of the VNC server.
*
* Parameters:
* display - In the case of hardware with multiple displays, this
* specifies the display. Normally this is zero.
* kbdout - If non-NULL, then the pointed-to function will be called to
* handle all keyboard input as it is received. This may be either raw,
* ASCII keypress input or encoded keyboard input as determined by
* CONFIG_VNCSERVER_KBDENCODE. See include/nuttx/input/kbd_codec.h.
* mouseout - If non-NULL, then the pointed-to function will be called to
* handle all mouse input as it is received.
* arg - An opaque user provided argument that will be provided when the
* callouts are performed.
*
* Returned Value:
* Zero (OK) is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
int vnc_fbinitialize(int display, vnc_kbdout_t kbdout,
vnc_mouseout_t mouseout, FAR void *arg)
{
FAR struct vnc_session_s *session;
int ret;
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
/* Start the VNC server kernel thread. */
ret = vnc_start_server(display);
if (ret < 0)
{
gvdbg("ERROR: vnc_start_server() failed: %d\n", ret);
return ret;
}
/* Wait for the VNC server to start and complete initialization. */
ret = vnc_wait_start(display);
if (ret < 0)
{
gvdbg("ERROR: vnc_wait_start() failed: %d\n", ret);
return ret;
}
/* Save the input callout function information in the session structure. */
session = g_vnc_sessions[display];
DEBUGASSERT(session != NULL);
session->kbdout = kbdout;
session->mouseout = mouseout;
session->arg = arg;
return OK;
}
/****************************************************************************
@ -550,12 +756,15 @@ int up_fbinitialize(int display)
FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
{
FAR struct vnc_session_s *session = vnc_find_session(display);
FAR struct vnc_session_s *session;
FAR struct vnc_fbinfo_s *fbinfo;
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[display];
/* Verify that the session is still valid */
if (session->state != VNCSERVER_RUNNING)
if (session == NULL || session->state != VNCSERVER_RUNNING)
{
return NULL;
}
@ -607,14 +816,21 @@ FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane)
void up_fbuninitialize(int display)
{
#if 0 /* Do nothing */
FAR struct vnc_session_s *session = vnc_find_session(display);
FAR struct vnc_session_s *session;
FAR struct vnc_fbinfo_s *fbinfo;
DEBUGASSERT(session != NULL);
fbinfo = &g_fbinfo[display];
DEBUGASSERT(display >= 0 && display < RFB_MAX_DISPLAYS);
session = g_vnc_sessions[display];
/* Verify that the session is still valid */
if (session != NULL)
{
fbinfo = &g_fbinfo[display];
#warning Missing logic
UNUSED(session);
UNUSED(fbinfo);
UNUSED(session);
UNUSED(fbinfo);
}
#endif
}
@ -653,7 +869,7 @@ void nx_notify_rectangle(FAR NX_PLANEINFOTYPE *pinfo,
*/
DEBUGASSERT(pinfo->display >= 0 && pinfo->display < RFB_MAX_DISPLAYS);
session = vnc_find_session(pinfo->display);
session = g_vnc_sessions[pinfo->display];
/* Verify that the session is still valid */
@ -661,7 +877,7 @@ void nx_notify_rectangle(FAR NX_PLANEINFOTYPE *pinfo,
{
/* Queue the rectangular update */
ret = vnc_update_rectangle(session, rect);
ret = vnc_update_rectangle(session, rect, true);
if (ret < 0)
{
gdbg("ERROR: vnc_update_rectangle failed: %d\n", ret);

View File

@ -48,6 +48,8 @@
#define XK_LATIN1 1
#define XK_XKB_KEYS 1
#include <nuttx/nx/nx.h>
#include <nuttx/video/vnc.h>
#include <nuttx/input/x11_keysymdef.h>
#include <nuttx/input/kbd_codec.h>
@ -481,9 +483,10 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym,
#ifdef CONFIG_VNCSERVER_KBDENCODE
uint8_t buffer[4]
int nch;
#else
uint8_t buffer;
#endif
int16_t keych;
int ret;
/* Check for modifier keys */
@ -505,6 +508,14 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym,
}
#endif
/* If no external keyboard input handler has been provided, then we have to drop the keyboard input.
*/
if (session->kbdout == NULL)
{
return;
}
/* Try to convert the keycode to an ASCII value */
keych = vnc_kbd_ascii((char)(keysym & 255));
@ -580,19 +591,12 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym,
/* Inject the normal character sequence into NX */
ret = nx_kbdin(session->handle, nch, buffer);
if (ret < 0)
{
gdbg("ERROR: nx_kbdin() failed: %d\n", ret);
}
session->kbdout(session->arg, nch, buffer);
#else
/* Inject the single key press into NX */
ret = nx_kbdchin(session->handle,(uint8_t)keych);
if (ret < 0)
{
gdbg("ERROR: nx_kbdchin() failed: %d\n", ret);
}
buffer = (uint8_t)keych;
session->kbdout(session->arg, 1, &buffer);
#endif
}
@ -619,14 +623,32 @@ void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym,
/* Inject the special character sequence into NX */
ret = nx_kbdin(session->handle, nch, buffer);
if (ret < 0)
{
gdbg("ERROR: nx_kbdin() failed: %d\n", ret)
}
session->kbdout(session->arg, nch, buffer);
}
}
#endif
}
/****************************************************************************
* Function: vnc_kbdout
*
* Description:
* This is the default keyboard callout function. This is simply wrappers around nx_kdbout(), respectively. When configured using vnc_fbinitialize(), the 'arg' must be the correct NXHANDLE value.
*
* Parameters:
* arg - The NXHANDLE from the NX graphics subsystem
* nch - Number of characters
* ch - An array of input characters.
*
* Returned Value:
* None
*
****************************************************************************/
void vnc_kbdout(FAR void *arg, uint8_t nch, FAR const uint8_t *ch)
{
DEBUGASSERT(arg != NULL);
(void)nx_kbdin((NXHANDLE)arg, nch, ch);
}
#endif /* CONFIG_NX_KBD */

View File

@ -43,6 +43,14 @@
#include <string.h>
#include <errno.h>
#include <assert.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#ifdef CONFIG_NET_SOCKOPTS
@ -154,6 +162,11 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
DEBUGASSERT(errcode > 0);
return -errcode;
}
else if (nrecvd == 0)
{
gdbg("Connection closed\n");
return -ECONNABORTED;
}
DEBUGASSERT(nrecvd == len);
@ -221,6 +234,11 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
DEBUGASSERT(errcode > 0);
return -errcode;
}
else if (nrecvd == 0)
{
gdbg("Connection closed\n");
return -ECONNABORTED;
}
DEBUGASSERT(nrecvd == sizeof(struct rfb_selected_sectype_s));
@ -305,6 +323,11 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
DEBUGASSERT(errcode > 0);
return -errcode;
}
else if (nrecvd == 0)
{
gdbg("Connection closed\n");
return -ECONNABORTED;
}
DEBUGASSERT(nrecvd == sizeof(struct rfb_clientinit_s));
@ -375,6 +398,11 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
DEBUGASSERT(errcode > 0);
return -errcode;
}
else if (nrecvd == 0)
{
gdbg("Connection closed\n");
return -ECONNABORTED;
}
else if (nrecvd != sizeof(struct rfb_setpixelformat_s))
{
/* Must not be a SetPixelFormat message? */
@ -384,12 +412,13 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
}
else if (setformat->msgtype != RFB_SETPIXELFMT_MSG)
{
gdbg("ERROR: Not a SetPixelFormat message: %d\n", (int)setformat->msgtype);
gdbg("ERROR: Not a SetPixelFormat message: %d\n",
(int)setformat->msgtype);
return -EPROTO;
}
/* Instantiate the client pixel format, verifying that the client request format
* is one that we can handle.
/* Instantiate the client pixel format, verifying that the client request
* format is one that we can handle.
*/
ret = vnc_client_pixelformat(session, &setformat->format);
@ -408,7 +437,7 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
encodings = (FAR struct rfb_setencodings_s *)session->inbuf;
nrecvd = psock_recv(&session->connect, encodings,
CONFIG_VNCSERVER_INBUFFER_SIZE, 0);
CONFIG_VNCSERVER_INBUFFER_SIZE, 0);
if (nrecvd < 0)
{
errcode = get_errno();
@ -416,10 +445,15 @@ int vnc_negotiate(FAR struct vnc_session_s *session)
DEBUGASSERT(errcode > 0);
return -errcode;
}
if (nrecvd > 0 && encodings->msgtype == RFB_SETENCODINGS_MSG)
else if (nrecvd == 0)
{
DEBUGASSERT(nrecvd >= SIZEOF_RFB_SETENCODINGS_S(0));
gdbg("Connection closed\n");
return -ECONNABORTED;
}
if (encodings->msgtype == RFB_SETENCODINGS_MSG)
{
DEBUGASSERT(nrecvd >= SIZEOF_RFB_SETENCODINGS_S(0));
/* Pick out any mutually supported encodings */
@ -465,37 +499,43 @@ int vnc_client_pixelformat(FAR struct vnc_session_s *session,
if (pixelfmt->bpp == 8 && pixelfmt->depth == 6)
{
gvdbg("Client pixel format: RGB8 2:2:2\n");
session->colorfmt = FB_FMT_RGB8_222;
session->bpp = 8;
session->colorfmt = FB_FMT_RGB8_222;
session->bpp = 8;
session->bigendian = false;
}
else if (pixelfmt->bpp == 8 && pixelfmt->depth == 8)
{
gvdbg("Client pixel format: RGB8 3:3:2\n");
session->colorfmt = FB_FMT_RGB8_332;
session->bpp = 8;
session->colorfmt = FB_FMT_RGB8_332;
session->bpp = 8;
session->bigendian = false;
}
else if (pixelfmt->bpp == 16 && pixelfmt->depth == 15)
{
gvdbg("Client pixel format: RGB16 5:5:5\n");
session->colorfmt = FB_FMT_RGB16_555;
session->bpp = 16;
session->colorfmt = FB_FMT_RGB16_555;
session->bpp = 16;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else if (pixelfmt->bpp == 16 && pixelfmt->depth == 16)
{
gvdbg("Client pixel format: RGB16 5:6:5\n");
session->colorfmt = FB_FMT_RGB16_565;
session->bpp = 16;
session->colorfmt = FB_FMT_RGB16_565;
session->bpp = 16;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 24)
{
gvdbg("Client pixel format: RGB32 8:8:8\n");
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else if (pixelfmt->bpp == 32 && pixelfmt->depth == 32)
{
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->colorfmt = FB_FMT_RGB32;
session->bpp = 32;
session->bigendian = (pixelfmt->bigendian != 0) ? true : false;
}
else
{
@ -506,5 +546,6 @@ int vnc_client_pixelformat(FAR struct vnc_session_s *session,
return -ENOSYS;
}
session->change = true;
return OK;
}

View File

@ -42,6 +42,14 @@
#include <stdint.h>
#include <assert.h>
#include <errno.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#include "vnc_server.h"
@ -135,14 +143,16 @@ static size_t vnc_copy16(FAR struct vnc_session_s *session,
FAR struct rfb_framebufferupdate_s *update;
FAR const lfb_color_t *srcleft;
FAR const lfb_color_t *src;
FAR uint16_t *dest;
FAR uint8_t *dest;
uint16_t pixel;
nxgl_coord_t x;
nxgl_coord_t y;
bool bigendian;
/* Destination rectangle start address */
update = (FAR struct rfb_framebufferupdate_s *)session->outbuf;
dest = (FAR uint16_t *)update->rect[0].data;
dest = (FAR uint8_t *)update->rect[0].data;
/* Source rectangle start address (left/top)*/
@ -150,12 +160,24 @@ static size_t vnc_copy16(FAR struct vnc_session_s *session,
/* Transfer each row from the source buffer into the update buffer */
bigendian = session->bigendian;
for (y = 0; y < height; y++)
{
src = srcleft;
for (x = 0; x < width; x++)
{
*dest++ = convert(*src);
pixel = convert(*src);
if (bigendian)
{
rfb_putbe16(dest, pixel);
}
else
{
rfb_putle16(dest, pixel);
}
dest += sizeof(uint16_t);
src++;
}
@ -192,14 +214,16 @@ static size_t vnc_copy32(FAR struct vnc_session_s *session,
FAR struct rfb_framebufferupdate_s *update;
FAR const lfb_color_t *srcleft;
FAR const lfb_color_t *src;
FAR uint32_t *dest;
FAR uint8_t *dest;
nxgl_coord_t x;
nxgl_coord_t y;
uint32_t pixel;
bool bigendian;
/* Destination rectangle start address */
update = (FAR struct rfb_framebufferupdate_s *)session->outbuf;
dest = (FAR uint32_t *)update->rect[0].data;
dest = (FAR uint8_t *)update->rect[0].data;
/* Source rectangle start address (left/top)*/
@ -207,12 +231,24 @@ static size_t vnc_copy32(FAR struct vnc_session_s *session,
/* Transfer each row from the source buffer into the update buffer */
bigendian = session->bigendian;
for (y = 0; y < height; y++)
{
src = srcleft;
for (x = 0; x < width; x++)
{
*dest++ = convert(*src);
pixel = convert(*src);
if (bigendian)
{
rfb_putbe32(dest, pixel);
}
else
{
rfb_putle32(dest, pixel);
}
dest += sizeof(uint32_t);
src++;
}
@ -454,6 +490,9 @@ int vnc_raw(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect)
size -= nsent;
}
while (size > 0);
updvdbg("Sent {(%d, %d),(%d, %d)}\n",
x, y, x + updwidth -1, y + updheight - 1);
}
}
}

View File

@ -41,6 +41,14 @@
#include <assert.h>
#include <errno.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#ifdef CONFIG_NET_SOCKOPTS
@ -49,6 +57,9 @@
#include <nuttx/net/net.h>
#include <nuttx/video/rfb.h>
#include <nuttx/video/vnc.h>
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxglib.h>
#include "vnc_server.h"
@ -165,6 +176,16 @@ int vnc_receiver(FAR struct vnc_session_s *session)
return -errcode;
}
/* A return value of zero means that the connection was gracefully
* closed by the VNC client.
*/
else if (nrecvd == 0)
{
gdbg("Connection closed\n", errcode);
return OK;
}
DEBUGASSERT(nrecvd == 1);
/* The single byte received should be the message type. Handle the
@ -207,7 +228,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
case RFB_SETENCODINGS_MSG: /* SetEncodings */
{
FAR struct rfb_setencodings_s *encodings;
uint32_t nencodings;
unsigned int nencodings;
gvdbg("Received SetEncodings\n");
@ -228,7 +249,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
/* Read the following encodings */
encodings = (FAR struct rfb_setencodings_s *)session->inbuf;
nencodings = rfb_getbe32(encodings->nencodings);
nencodings = rfb_getbe16(encodings->nencodings);
ret = vnc_read_remainder(session,
nencodings * sizeof(uint32_t),
@ -280,7 +301,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
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);
ret = vnc_update_rectangle(session, &rect, false);
if (ret < 0)
{
gdbg("ERROR: Failed to queue update: %d\n", ret);
@ -337,7 +358,7 @@ int vnc_receiver(FAR struct vnc_session_s *session)
#ifdef CONFIG_NX_XYINPUT
/* REVISIT: How will be get the NX handle? */
else if (session->handle != NULL)
else if (session->mouseout != NULL)
{
event = (FAR struct rfb_pointerevent_s *)session->inbuf;
@ -362,14 +383,10 @@ int vnc_receiver(FAR struct vnc_session_s *session)
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);
}
session->mouseout(session->arg,
(nxgl_coord_t)rfb_getbe16(event->xpos),
(nxgl_coord_t)rfb_getbe16(event->ypos),
buttons);
}
#endif
}
@ -456,7 +473,7 @@ int vnc_client_encodings(FAR struct vnc_session_s *session,
/* Loop for each client supported encoding */
nencodings = rfb_getbe32(encodings->nencodings);
nencodings = rfb_getbe16(encodings->nencodings);
for (i = 0; i < nencodings; i++)
{
/* Get the next encoding */
@ -468,9 +485,37 @@ int vnc_client_encodings(FAR struct vnc_session_s *session,
if (encoding == RFB_ENCODING_RRE)
{
session->rre = true;
return OK;
}
}
session->change = true;
return OK;
}
/****************************************************************************
* Function: vnc_mouse
*
* Description:
* This is the default keyboard/mouse callout function. This is simply a
* wrapper around nx_mousein(). When
* configured using vnc_fbinitialize(), the 'arg' must be the correct
* NXHANDLE value.
*
* Parameters:
* See vnc_mouseout_t and vnc_kbdout_t typde definitions above. These
* callouts have arguments that match the inputs to nx_kbdin() and
* nx_mousein() (if arg is really of type NXHANDLE).
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_XYINPUT
void vnc_mouseout(FAR void *arg, nxgl_coord_t x, nxgl_coord_t y,
uint8_t buttons)
{
DEBUGASSERT(arg != NULL);
(void)nx_mousein((NXHANDLE)arg, x, y, buttons);
}
#endif

View File

@ -42,6 +42,14 @@
#include <stdint.h>
#include <assert.h>
#include <errno.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#include "vnc_server.h"
@ -50,35 +58,119 @@
* Private Types
****************************************************************************/
struct rre_data_s
struct rre_encode8_s
{
#if RFB_BITSPERPIXEL == 16
struct rfb_rrehdr16_s hdr; /* Header with background pixel */
struct rfb_rrerect16_s srect; /* Sub-rectangle */
#elif RFB_BITSPERPIXEL == 32
struct rfb_rrehdr32_s hdr; /* Header with background pixel */
struct rfb_rrerect32_s srect; /* Sub-rectangle */
#endif
struct rfb_rrehdr8_s hdr;
struct rfb_rrerect8_s rect;
};
struct rre_rectangle_s
struct rre_encode16_s
{
uint8_t xpos[2]; /* U16 X position */
uint8_t ypos[2]; /* U16 Y position */
uint8_t width[2]; /* U16 Width */
uint8_t height[2]; /* U16 Height */
uint8_t encoding[4]; /* S32 Encoding type = RFB_ENCODING_RRE */
struct rre_data_s data; /* Pixel data, actual size varies */
struct rfb_rrehdr16_s hdr;
struct rfb_rrerect16_s rect;
};
struct rre_framebufferupdate_s
struct rre_encode32_s
{
uint8_t msgtype; /* U8 Message type = RFB_FBUPDATE_MSG*/
uint8_t padding;
uint8_t nrect[2]; /* U16 Number of rectangles = 1*/
struct rre_rectangle_s rect; /* RRE encoded rectangle */
struct rfb_rrehdr32_s hdr;
struct rfb_rrerect32_s rect;
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: vnc_rreNN
*
* Description:
* Encode a single RRE sub-rectangle, NN=bits-per-pixel
*
* Input Parameters:
* session - An instance of the session structure.
* dest - The locate to save the RRE encoded data
* rect - Describes the rectangle in the local framebuffer.
* bgcolor - The local color of the pixel data
*
* Returned Value:
* The size of the framebuffer update message is returned..
*
****************************************************************************/
ssize_t vnc_rre8(FAR struct vnc_session_s *session,
FAR struct rre_encode8_s *dest,
FAR struct nxgl_rect_s *rect,
uint8_t bgcolor)
{
nxgl_coord_t width;
nxgl_coord_t height;
rfb_putbe32(dest->hdr.nsubrects, 1);
dest->hdr.pixel = bgcolor;
dest->rect.pixel = bgcolor;
rfb_putbe16(dest->rect.xpos, rect->pt1.x);
rfb_putbe16(dest->rect.ypos, rect->pt1.y);
width = rect->pt2.x - rect->pt1.x + 1;
height = rect->pt2.y - rect->pt1.y + 1;
rfb_putbe16(dest->rect.width, width);
rfb_putbe16(dest->rect.height, height);
return sizeof(struct rre_encode8_s);
}
ssize_t vnc_rre16(FAR struct vnc_session_s *session,
FAR struct rre_encode16_s *dest,
FAR struct nxgl_rect_s *rect,
uint16_t bgcolor)
{
nxgl_coord_t width;
nxgl_coord_t height;
rfb_putbe32(dest->hdr.nsubrects, 1);
rfb_putbe16(dest->hdr.pixel, bgcolor);
rfb_putbe16(dest->rect.pixel, bgcolor);
rfb_putbe16(dest->rect.xpos, rect->pt1.x);
rfb_putbe16(dest->rect.xpos, rect->pt1.x);
rfb_putbe16(dest->rect.ypos, rect->pt1.y);
width = rect->pt2.x - rect->pt1.x + 1;
height = rect->pt2.y - rect->pt1.y + 1;
rfb_putbe16(dest->rect.width, width);
rfb_putbe16(dest->rect.height, height);
return sizeof(struct rre_encode16_s);
}
ssize_t vnc_rre32(FAR struct vnc_session_s *session,
FAR struct rre_encode32_s *dest,
FAR struct nxgl_rect_s *rect,
uint32_t bgcolor)
{
nxgl_coord_t width;
nxgl_coord_t height;
rfb_putbe32(dest->hdr.nsubrects, 1);
rfb_putbe32(dest->hdr.pixel, bgcolor);
rfb_putbe32(dest->rect.pixel, bgcolor);
rfb_putbe16(dest->rect.xpos, rect->pt1.x);
rfb_putbe16(dest->rect.xpos, rect->pt1.x);
rfb_putbe16(dest->rect.ypos, rect->pt1.y);
width = rect->pt2.x - rect->pt1.x + 1;
height = rect->pt2.y - rect->pt1.y + 1;
rfb_putbe16(dest->rect.width, width);
rfb_putbe16(dest->rect.height, height);
return sizeof(struct rre_encode32_s);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -97,22 +189,21 @@ struct rre_framebufferupdate_s
*
* Returned Value:
* Zero is returned if RRE coding was not performed (but not error was)
* encountered. Otherwise, eith the size of the framebuffer update
* message is returned on success or a negated errno value is returned on
* failure that indicates the the nature of the failure. A failure is
* only returned in cases of a network failure and unexpected internal
* failures.
* encountered. Otherwise, the size of the framebuffer update message
* is returned on success or a negated errno value is returned on failure
* that indicates the the nature of the failure. A failure is only
* returned in cases of a network failure and unexpected internal failures.
*
****************************************************************************/
int vnc_rre(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect)
{
FAR struct rre_framebufferupdate_s *rre;
FAR struct rre_rectangle_s *rrect;
FAR struct rre_data_s *rdata;
FAR struct rfb_framebufferupdate_s *rre;
FAR struct rfb_rectangle_s *rrect;
lfb_color_t bgcolor;
nxgl_coord_t width;
nxgl_coord_t height;
size_t nbytes;
ssize_t nsent;
int ret;
@ -125,38 +216,66 @@ int vnc_rre(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect)
ret = vnc_colors(session, rect, 1, &bgcolor);
if (ret == 1)
{
width = rect->pt2.x - rect->pt1.x + 1;
height = rect->pt2.y - rect->pt1.y + 1;
width = rect->pt2.x - rect->pt1.x + 1;
height = rect->pt2.y - rect->pt1.y + 1;
/* Format the FrameBuffer Update with a single RRE encoded
* rectangle.
*/
rre = (FAR struct rre_framebufferupdate_s *)session->outbuf;
rre = (FAR struct rfb_framebufferupdate_s *)session->outbuf;
rre->msgtype = RFB_FBUPDATE_MSG;
rre->padding = 0;
rfb_putbe16(rre->nrect, 1);
rrect = (FAR struct rre_rectangle_s *)&rre->rect;
rrect = (FAR struct rfb_rectangle_s *)&rre->rect;
rfb_putbe16(rrect->xpos, rect->pt1.x);
rfb_putbe16(rrect->ypos, rect->pt1.y);
rfb_putbe16(rrect->width, width);
rfb_putbe16(rrect->height, height);
rfb_putbe32(rrect->encoding, RFB_ENCODING_RRE);
rdata = (FAR struct rre_data_s *)&rrect->data;
rfb_putbe32(rdata->hdr.nsubrects, 1);
#if RFB_BITSPERPIXEL == 16
rfb_putbe16(rdata->hdr.pixel, bgcolor);
rfb_putbe16(rdata->srect.pixel, bgcolor);
#elif RFB_BITSPERPIXEL == 32
rfb_putbe32(rdata->hdr.pixel, bgcolor);
rfb_putbe32(rdata->srect.pixel, bgcolor);
#endif
rfb_putbe16(rdata->srect.xpos, rect->pt1.x);
rfb_putbe16(rdata->srect.ypos, rect->pt1.y);
rfb_putbe16(rdata->srect.width, width);
rfb_putbe16(rdata->srect.height, height);
/* The sub-rectangle encoding depends of the remote pixel width */
nbytes = SIZEOF_RFB_FRAMEBUFFERUPDATE_S(SIZEOF_RFB_RECTANGE_S(0));
switch (session->colorfmt)
{
case FB_FMT_RGB8_222:
nbytes += vnc_rre8(session,
(FAR struct rre_encode8_s *)rrect->data,
rect, vnc_convert_rgb8_222(bgcolor));
break;
case FB_FMT_RGB8_332:
nbytes += vnc_rre8(session,
(FAR struct rre_encode8_s *)rrect->data,
rect, vnc_convert_rgb8_332(bgcolor));
break;
case FB_FMT_RGB16_555:
nbytes += vnc_rre16(session,
(FAR struct rre_encode16_s *)rrect->data,
rect, vnc_convert_rgb16_555(bgcolor));
break;
case FB_FMT_RGB16_565:
nbytes += vnc_rre16(session,
(FAR struct rre_encode16_s *)rrect->data,
rect, vnc_convert_rgb16_565(bgcolor));
break;
case FB_FMT_RGB32:
nbytes += vnc_rre32(session,
(FAR struct rre_encode32_s *)rrect->data,
rect, vnc_convert_rgb32_888(bgcolor));
break;
default:
gdbg("ERROR: Unrecognized color format: %d\n",
session->colorfmt);
return -EINVAL;
}
/* At the very last most, make certain that the supported encoding
* has not changed asynchronously.
@ -169,8 +288,7 @@ int vnc_rre(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect)
* and there are a limited number of IOBs available.
*/
nsent = psock_send(&session->connect, rre,
sizeof(struct rre_framebufferupdate_s), 0);
nsent = psock_send(&session->connect, rre, nbytes, 0);
if (nsent < 0)
{
int errcode = get_errno();
@ -180,8 +298,10 @@ int vnc_rre(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect)
return -errcode;
}
DEBUGASSERT(nsent == sizeof(struct rre_framebufferupdate_s));
return sizeof(struct rre_framebufferupdate_s);
DEBUGASSERT(nsent == nbytes);
updvdbg("Sent {(%d, %d),(%d, %d)}\n",
rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y);
return nbytes;
}
return -EINVAL;

View File

@ -46,6 +46,14 @@
#include <queue.h>
#include <assert.h>
#include <errno.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#include <arpa/inet.h>
@ -121,9 +129,11 @@ static void vnc_reset_session(FAR struct vnc_session_s *session,
sem_reset(&session->freesem, CONFIG_VNCSERVER_NUPDATES);
sem_reset(&session->queuesem, 0);
session->fb = fb;
session->display = display;
session->state = VNCSERVER_INITIALIZED;
session->change = true;
}
/****************************************************************************
@ -271,6 +281,11 @@ int vnc_server(int argc, FAR char *argv[])
sem_init(&session->freesem, 0, CONFIG_VNCSERVER_NUPDATES);
sem_init(&session->queuesem, 0, 0);
/* Inform any waiter that we have started */
vnc_reset_session(session, fb, display);
sem_post(&g_fbstartup[display].fbinit);
/* Loop... handling each each VNC client connection to this display. Only
* a single client is allowed for each display.
*/
@ -283,7 +298,7 @@ int vnc_server(int argc, FAR char *argv[])
vnc_reset_session(session, fb, display);
g_fbstartup[display].result = -EBUSY;
sem_reset(&g_fbstartup[display].fbsem, 0);
sem_reset(&g_fbstartup[display].fbconnect, 0);
/* Establish a connection with the VNC client */
@ -321,7 +336,7 @@ int vnc_server(int argc, FAR char *argv[])
*/
g_fbstartup[display].result = OK;
sem_post(&g_fbstartup[display].fbsem);
sem_post(&g_fbstartup[display].fbconnect);
/* Run the VNC receiver on this trhead. The VNC receiver handles
* all Client-to-Server messages. The VNC receiver function does
@ -331,6 +346,7 @@ int vnc_server(int argc, FAR char *argv[])
ret = vnc_receiver(session);
gvdbg("Session terminated with %d\n", ret);
UNUSED(ret);
/* Stop the VNC updater thread. */
@ -347,36 +363,6 @@ errout_with_fb:
errout_with_post:
g_fbstartup[display].result = ret;
sem_post(&g_fbstartup[display].fbsem);
sem_post(&g_fbstartup[display].fbconnect);
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;
}

View File

@ -49,6 +49,7 @@
#include <nuttx/video/fb.h>
#include <nuttx/video/rfb.h>
#include <nuttx/video/vnc.h>
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nx.h>
#include <nuttx/net/net.h>
@ -181,6 +182,34 @@
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
/* Debug */
#ifdef CONFIG_VNCSERVER_UPDATE_DEBUG
# ifdef CONFIG_CPP_HAVE_VARARGS
# define upddbg(format, ...) dbg(format, ##__VA_ARGS__)
# define updlldbg(format, ...) lldbg(format, ##__VA_ARGS__)
# define updvdbg(format, ...) vdbg(format, ##__VA_ARGS__)
# define updllvdbg(format, ...) llvdbg(format, ##__VA_ARGS__)
# else
# define upddbg dbg
# define updlldbg lldbg
# define updvdbg vdbg
# define updllvdbg llvdbg
# endif
#else
# ifdef CONFIG_CPP_HAVE_VARARGS
# define upddbg(x...)
# define updlldbg(x...)
# define updvdbg(x...)
# define updllvdbg(x...)
# else
# define upddbg (void)
# define updlldbg (void)
# define updvdbg (void)
# define updllvdbg (void)
# endif
#endif
/****************************************************************************
* Public Types
****************************************************************************/
@ -205,29 +234,35 @@ enum vnc_server_e
struct vnc_fbupdate_s
{
FAR struct vnc_fbupdate_s *flink;
bool whupd; /* True: whole screen update */
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 */
volatile uint8_t nwhupd; /* Number of whole screen updates queued */
volatile bool change; /* True: Frambebuffer data change since last whole screen update */
/* Display geometry and color characteristics */
uint8_t display; /* Display number (for debug) */
volatile uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */
volatile uint8_t bpp; /* Remote bits per pixel */
volatile bool rre; /* Remote supports RRE encoding */
volatile bool bigendian; /* True: Remote expect data in big-endian format */
volatile bool rre; /* True: Remote supports RRE encoding */
FAR uint8_t *fb; /* Allocated local frame buffer */
/* VNC client input support */
vnc_kbdout_t kbdout; /* Callout when keyboard input is received */
vnc_mouseout_t mouseout; /* Callout when keyboard input is received */
FAR void *arg; /* Argument that accompanies the callouts */
/* Updater information */
pthread_t updater; /* Updater thread ID */
@ -252,7 +287,8 @@ struct vnc_session_s
struct fb_startup_s
{
sem_t fbsem; /* Framebuffer driver will wait on this */
sem_t fbinit; /* Wait for session creation */
sem_t fbconnect; /* Wait for client connection */
int16_t result; /* OK: successfully initialized */
};
@ -415,6 +451,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session);
* Input Parameters:
* session - An instance of the session structure.
* rect - The rectanglular region to be updated.
* change - True: Frame buffer data has changed
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
@ -423,7 +460,8 @@ int vnc_stop_updater(FAR struct vnc_session_s *session);
****************************************************************************/
int vnc_update_rectangle(FAR struct vnc_session_s *session,
FAR const struct nxgl_rect_s *rect);
FAR const struct nxgl_rect_s *rect,
bool change);
/****************************************************************************
* Name: vnc_receiver
@ -455,11 +493,10 @@ int vnc_receiver(FAR struct vnc_session_s *session);
*
* Returned Value:
* Zero is returned if RRE coding was not performed (but not error was)
* encountered. Otherwise, eith the size of the framebuffer update
* message is returned on success or a negated errno value is returned on
* failure that indicates the the nature of the failure. A failure is
* only returned in cases of a network failure and unexpected internal
* failures.
* encountered. Otherwise, the size of the framebuffer update message
* is returned on success or a negated errno value is returned on failure
* that indicates the the nature of the failure. A failure is only
* returned in cases of a network failure and unexpected internal failures.
*
****************************************************************************/
@ -507,24 +544,6 @@ 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);
/****************************************************************************
* Name: vnc_convert_rgbNN
*

View File

@ -47,6 +47,17 @@
#include <assert.h>
#include <errno.h>
#if defined(CONFIG_VNCSERVER_DEBUG) && !defined(CONFIG_DEBUG_GRAPHICS)
# undef CONFIG_DEBUG
# undef CONFIG_DEBUG_VERBOSE
# define CONFIG_DEBUG 1
# define CONFIG_DEBUG_VERBOSE 1
# define CONFIG_DEBUG_GRAPHICS 1
#endif
#include <debug.h>
#include <nuttx/semaphore.h>
#include "vnc_server.h"
/****************************************************************************
@ -63,6 +74,20 @@
static sem_t g_dbgsem = SEM_INITIALIZER(1);
#endif
/* A rectangle represent the entire local framebuffer */
static const struct nxgl_rect_s g_wholescreen =
{
{
0,
0
},
{
CONFIG_VNCSERVER_SCREENWIDTH - 1,
CONFIG_VNCSERVER_SCREENHEIGHT - 1
}
};
/****************************************************************************
* Private Functions
****************************************************************************/
@ -237,11 +262,18 @@ vnc_remove_queue(FAR struct vnc_session_s *session)
/* It is reserved.. go get it */
rect = (FAR struct vnc_fbupdate_s *)sq_remfirst(&session->updqueue);
DEBUGASSERT(rect != NULL);
/* Check if we just removed the whole screen update from the queue */
if (session->nwhupd > 0 && rect->whupd)
{
session->nwhupd--;
updvdbg("Whole screen update: nwhupd=%d\n", session->nwhupd);
}
vnc_sem_debug(session, "After remove", 0);
sched_unlock();
DEBUGASSERT(rect != NULL);
return rect;
}
@ -325,6 +357,10 @@ static FAR void *vnc_updater(FAR void *arg)
srcrect = vnc_remove_queue(session);
DEBUGASSERT(srcrect != NULL);
updvdbg("Dequeued {(%d, %d),(%d, %d)}\n",
srcrect->rect.pt1.x, srcrect->rect.pt1.y,
srcrect->rect.pt2.x, srcrect->rect.pt2.y);
/* Attempt to use RRE encoding */
ret = vnc_rre(session, &srcrect->rect);
@ -454,6 +490,7 @@ int vnc_stop_updater(FAR struct vnc_session_s *session)
* Input Parameters:
* session - An instance of the session structure.
* rect - The rectanglular region to be updated.
* change - True: Frame buffer data has changed
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
@ -462,40 +499,103 @@ int vnc_stop_updater(FAR struct vnc_session_s *session)
****************************************************************************/
int vnc_update_rectangle(FAR struct vnc_session_s *session,
FAR const struct nxgl_rect_s *rect)
FAR const struct nxgl_rect_s *rect, bool change)
{
FAR struct vnc_fbupdate_s *update;
struct nxgl_rect_s intersection;
bool whupd;
/* Make sure that the rectangle has a area */
/* Clip rectangle to the screen dimensions */
if (!nxgl_nullrect(rect))
nxgl_rectintersect(&intersection, rect, &g_wholescreen);
/* Make sure that the clipped rectangle has a area */
if (!nxgl_nullrect(&intersection))
{
/* Allocate an update structure... waiting if necessary */
/* Check for a whole screen update. The RealVNC client sends a lot
* of these (especially when it is confused)
*/
update = vnc_alloc_update(session);
DEBUGASSERT(update != NULL);
whupd = (memcmp(&intersection, &g_wholescreen,
sizeof(struct nxgl_rect_s)) == 0);
/* Clip and copy the rectangle into the update structure */
/* Ignore any client update requests if there have been no changes to
* the framebuffer since the last whole screen update.
*/
update->rect.pt1.x = MAX(rect->pt1.x, 0);
update->rect.pt1.y = MAX(rect->pt1.y, 0);
update->rect.pt2.x = MIN(rect->pt2.x, (CONFIG_VNCSERVER_SCREENWIDTH - 1));
update->rect.pt2.y = MIN(rect->pt2.y, (CONFIG_VNCSERVER_SCREENHEIGHT - 1));
/* Make sure that the rectangle still has area after clipping */
if (nxgl_nullrect(rect))
sched_lock();
if (!change && !session->change)
{
/* No.. free the structure and ignore the update */
/* No.. ignore the client update. We have nothing new to report. */
vnc_free_update(session, update);
sched_unlock();
return OK;
}
else
/* Ignore all updates if there is a queued whole screen update */
if (session->nwhupd == 0)
{
/* Yes.. add the upate to the end of the update queue. */
/* No whole screen updates in the queue. Is this a new whole
* screen update?
*/
if (whupd)
{
/* Yes.. Discard all of the previously queued updates */
FAR struct vnc_fbupdate_s *curr;
FAR struct vnc_fbupdate_s *next;
updvdbg("New whole screen update...\n");
curr = (FAR struct vnc_fbupdate_s *)session->updqueue.head;
sq_init(&session->updqueue);
sem_reset(&session->queuesem, 0);
for (; curr != NULL; curr = next)
{
next = curr->flink;
vnc_free_update(session, curr);
}
/* One whole screen update will be queued. There have been
* no frame buffer data changes since this update was queued.
*/
session->nwhupd = 1;
session->change = false;
}
else
{
/* We are not updating the whole screen. Remember if this
* update (OR a preceding update) was due to a data change.
*/
session->change |= change;
}
/* Allocate an update structure... waiting if necessary */
update = vnc_alloc_update(session);
DEBUGASSERT(update != NULL);
/* Copy the clipped rectangle into the update structure */
update->whupd = whupd;
nxgl_rectcopy(&update->rect, &intersection);
/* Add the upate to the end of the update queue. */
vnc_add_queue(session, update);
updvdbg("Queued {(%d, %d),(%d, %d)}\n",
intersection.pt1.x, intersection.pt1.y,
intersection.pt2.x, intersection.pt2.y);
}
sched_unlock();
}
/* Since we ignore bad rectangles and wait for updata structures, there is

View File

@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/board.h
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -46,7 +46,8 @@
* definitions provide the common interface between NuttX and the
* architecture-specific implementation in arch/
*
* These definitions are retained in the the header file nuttx/include/arch.h
* These definitions are retained in the the header file
* nuttx/include/arch.h
*
* NOTE: up_ is supposed to stand for microprocessor; the u is like the
* Greek letter micron: µ. So it would be µP which is a common shortening
@ -680,7 +681,8 @@ xcpt_t board_button_irq(int id, xcpt_t irqhandler);
****************************************************************************/
#ifdef CONFIG_BOARD_CRASHDUMP
void board_crashdump(uint32_t currentsp, void *tcb, uint8_t *filename,
void board_crashdump(uintptr_t currentsp, FAR void *tcb,
FAR const uint8_t *filename,
int lineno);
#endif

View File

@ -370,8 +370,8 @@ struct rfb_setpixelformat_s
struct rfb_setencodings_s
{
uint8_t msgtype; /* U8 Message type */
uint8_t padding[3];
uint8_t nencodings[4]; /* U32 Number of encodings */
uint8_t padding;
uint8_t nencodings[2]; /* U16 Number of encodings */
uint8_t encodings[4]; /* S32 Encoding type, size = 4*nencodings */
};
@ -691,6 +691,12 @@ struct rfb_copyrect_encoding_s
* the header:"
*/
struct rfb_rrehdr8_s
{
uint8_t nsubrects[4]; /* U32 Number of sub-rectangle */
uint8_t pixel; /* U8 Background pixel */
};
struct rfb_rrehdr16_s
{
uint8_t nsubrects[4]; /* U32 Number of sub-rectangle */
@ -707,6 +713,15 @@ struct rfb_rrehdr32_s
* structure:"
*/
struct rfb_rrerect8_s
{
uint8_t pixel; /* U8 sub-rect pixel value */
uint8_t xpos[2]; /* U16 X position */
uint8_t ypos[2]; /* U16 Y position */
uint8_t width[2]; /* U16 Width */
uint8_t height[2]; /* U16 Height */
};
struct rfb_rrerect16_s
{
uint8_t pixel[2]; /* U16 sub-rect pixel value */
@ -771,6 +786,11 @@ struct rfb_rrerect32_s
* background colour for this tile:"
*/
struct rfb_backpixel8_s
{
uint8_t pixel; /* U8 Background pixel value */
};
struct rfb_backpixel16_s
{
uint8_t pixel[2]; /* U16 Background pixel value */
@ -788,6 +808,11 @@ struct rfb_backpixel32_s
* foreground colour to be used for all subrectangles in this tile:"
*/
struct rfb_forepixel8_s
{
uint8_t pixel; /* U8 Foreground pixel value */
};
struct rfb_forepixel16_s
{
uint8_t pixel[2]; /* U16 Foreground pixel value */
@ -816,6 +841,13 @@ struct rfb_nrects_s
* value giving the colour of that subrectangle, so a subrectangle is:"
*/
struct rfb_subrectscolored8_s
{
uint8_t pixel; /* U8 Sub-rect pixel value */
uint8_t xy; /* U8 X and y position */
uint8_t wh; /* U8 Width and height */
};
struct rfb_subrectscolored16_s
{
uint8_t pixel[2]; /* U16 Sub-rect pixel value */
@ -916,6 +948,14 @@ struct rfb_srle_s
* height are the width and height of the tile):"
*/
struct rfb_rawpixel8_s
{
uint8_t pixels[1]; /* Actual size is w*h */
};
#define SIZEOF_RFB_RAWPIXEL8_S(n,r) \
(sizeof(struct rfb_rawpixel8_s) + (n) - 1)
struct rfb_rawpixel16_s
{
uint8_t pixels[2]; /* Actual size is 2*w*h */
@ -934,6 +974,11 @@ struct rfb_rawpixel32_s
/* "A solid tile consisting of a single colour. The pixel value follows:" */
struct rfb_solid8_s
{
uint8_t pixels; /* Pixel value */
};
struct rfb_solid16_s
{
uint8_t pixels[2]; /* Pixel value */
@ -977,6 +1022,11 @@ struct rfb_solid32_s
* (subencoding 128) pixel values:"
*/
struct rfb_palette8_s
{
uint8_t palette[1]; /* Actual size is palleteSize */
};
struct rfb_palette16_s
{
uint8_t palette[2]; /* Actual size is 2*palleteSize */
@ -1081,6 +1131,48 @@ struct rfb_palettendx_s
((uint32_t)((s)[2]) << 8) | \
(uint32_t)((s)[3]))
/* There are also cases where the client may request pixel data in its
* little-endian format.
*/
/* void rfb_putle16(FAR uint8_t *dest, uint16_t value) */
#define rfb_putle16(d,v) \
do \
{ \
register FAR uint8_t *__d = (FAR uint8_t *)(d); \
*__d++ = ((uint16_t)(v) & 0xff); \
*__d = ((uint16_t)(v) >> 8); \
} \
while (0)
/* uin16_t rfb_getle16(FAR const uint8_t *src) */
#define rfb_getle16(s) \
(((uint16_t)((s)[1]) << 8) | \
(uint16_t)((s)[0]))
/* void rfb_putle32(FAR uint8_t *dest, uint32_t value) */
#define rfb_putle32(d,v) \
do \
{ \
register FAR uint8_t *__d = (FAR uint8_t *)(d); \
*__d++ = ((uint32_t)(v) & 0xff); \
*__d++ = ((uint32_t)(v) >> 8) & 0xff; \
*__d++ = ((uint32_t)(v) >> 16) & 0xff; \
*__d = ((uint32_t)(v) >> 24); \
} \
while (0)
/* uint32_t rfb_getle32(FAR const uint8_t *src) */
#define rfb_getle32(s) \
(((uint32_t)((s)[3]) << 24) | \
((uint32_t)((s)[2]) << 16) | \
((uint32_t)((s)[1]) << 8) | \
(uint32_t)((s)[0]))
/****************************************************************************
* Public Function Prototypes
****************************************************************************/

212
include/nuttx/video/vnc.h Normal file
View File

@ -0,0 +1,212 @@
/****************************************************************************
* include/nuttx/video/vnc.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 __INCLUDE_NUTTX_VIDEO_VNC_H
#define __INCLUDE_NUTTX_VIDEO_VNC_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <nuttx/nx/nxglib.h>
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* These are the types of the function pointers used to support callouts when
* mouse or keyboard inputs are received by the local VNC server from the
* remove VNC client. Notice that these callouts have arguments that match
* the inputs to nx_kbdin() and nx_mousein().
*/
typedef CODE void (*vnc_mouseout_t)(FAR void *arg, nxgl_coord_t x,
nxgl_coord_t y, uint8_t buttons);
typedef CODE void (*vnc_kbdout_t)(FAR void *arg, uint8_t nch,
FAR const uint8_t *ch);
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Function: vnc_fbinitialize
*
* Description:
* Initialize the VNC frame buffer driver. The VNC frame buffer driver
* supports two initialization interfaces: The standard up_fbinitialize()
* that will be called from the graphics layer and this speical
* initialization function that can be used only by VNC aware OS logic.
*
* The two initialization functions may be called separated or together in
* either order. The difference is that standard up_fbinitialize(), if
* used by itself, will not have any remote mouse or keyboard inputs that
* are reported to the VNC framebuffer driver from the remote VNC client.
*
* In the standard graphics architecture, the keyboard/mouse inputs are
* received by some appliation/board specific logic at the highest level
* in the architecture via input drivers. The received keyboard/mouse
* input data must then be "injected" into NX where it can they can be
* assigned to the window that has focus. They will eventually be
* received by the Window instances via NX callback methods.
*
* NX is a middleware layer in the architecture, below the
* application/board specific logic but above the driver level logic. The
* frame buffer driver, on the other hand lies at the very lowest level in
* the graphics architecture. It cannot call upward into the application
* nor can it call upward into NX. So, some other logic.
*
* vnc_fbinitialize() provides an optional, alternative initialization
* function. It is optional becuase it need not be called. If it is not
* called, however, keyboard/mouse inputs from the remote VNC client will
* be lost. By calling vnc_fbinitialize(), you can provide callout
* functions that can be received by logic higher in the architure. This
* higher level level callouts can then call nx_kbdin() or nx_mousein() on
* behalf of the VNC server.
*
* See also vnc_default_fbinitialize() below.
*
* Parameters:
* display - In the case of hardware with multiple displays, this
* specifies the display. Normally this is zero.
* kbdout - If non-NULL, then the pointed-to function will be called to
* handle all keyboard input as it is received. This may be either raw,
* ASCII keypress input or encoded keyboard input as determined by
* CONFIG_VNCSERVER_KBDENCODE. See include/nuttx/input/kbd_codec.h.
* mouseout - If non-NULL, then the pointed-to function will be called to
* handle all mouse input as it is received.
* arg - An opaque user provided argument that will be provided when the
* callouts are performed.
*
* Returned Value:
* Zero (OK) is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
int vnc_fbinitialize(int display, vnc_kbdout_t kbdout,
vnc_mouseout_t mouseout, FAR void *arg);
/****************************************************************************
* Function: vnc_mouse and vnc_kbdout
*
* Description:
* These are the default keyboard/mouse callout functions. They are
* simply wrappers around nx_mousein() and nx_kdbout(), respectively. When
* configured using vnc_fbinitialize(), the 'arg' must be the correct
* NXHANDLE value.
*
* See also vnc_default_fbinitialize() below.
*
* Parameters:
* See vnc_mouseout_t and vnc_kbdout_t typde definitions above. These
* callouts have arguments that match the inputs to nx_kbdin() and
* nx_mousein() (if arg is really of type NXHANDLE).
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_NX_KBD
void vnc_kbdout(FAR void *arg, uint8_t nch, FAR const uint8_t *ch);
#endif
#ifdef CONFIG_NX_XYINPUT
void vnc_mouseout(FAR void *arg, nxgl_coord_t x, nxgl_coord_t y,
uint8_t buttons);
#endif
/****************************************************************************
* Function: vnc_default_fbinitialize
*
* Description:
* This is just a wrapper around vnc_fbinitialize() that will establish
* the default mouse and keyboard callout functions.
*
* Parameters:
* display - In the case of hardware with multiple displays, this
* specifies the display. Normally this is zero.
* handle - And instance of NXHANDLE returned from initialization of the
* NX graphics system for that display.
*
* Returned Value:
* Zero (OK) is returned on success. Otherwise, a negated errno value is
* returned to indicate the nature of the failure.
*
****************************************************************************/
/* int vnc_default_fbinitialize(int display, NXHANDLE handle); */
#if defined(CONFIG_NX_KBD) && defined(CONFIG_NX_XYINPUT)
#define vnc_default_fbinitialize(d,h) \
vnc_fbinitialize((d), vnc_kbdout, vnc_mouseout, (FAR void *)(h))
#elif defined(CONFIG_NX_KBD)
#define vnc_default_fbinitialize(d,h) \
vnc_fbinitialize((d), vnc_kbdout, NULL, (FAR void *)(h))
#elif defined(CONFIG_NX_XYINPUT)
#define vnc_default_fbinitialize(d,h) \
vnc_fbinitialize((d), NULL, vnc_mouseout, (FAR void *)(h))
#else
#define vnc_default_fbinitialize(d,h) \
vnc_fbinitialize((d), NULL, NULL, NULL)
#endif
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* __INCLUDE_NUTTX_VIDEO_VNC_H */