Merged nuttx/nuttx into master
This commit is contained in:
commit
0b8f953f49
11
ChangeLog
11
ChangeLog
@ -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).
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
117
configs/samv71-xult/vnxwm/Make.defs
Normal file
117
configs/samv71-xult/vnxwm/Make.defs
Normal 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 =
|
||||
|
1567
configs/samv71-xult/vnxwm/defconfig
Normal file
1567
configs/samv71-xult/vnxwm/defconfig
Normal file
File diff suppressed because it is too large
Load Diff
77
configs/samv71-xult/vnxwm/setenv.sh
Normal file
77
configs/samv71-xult/vnxwm/setenv.sh
Normal 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}"
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -53,22 +53,6 @@
|
||||
|
||||
#ifdef CONFIG_NX_NXSTART
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
212
include/nuttx/video/vnc.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user