diff --git a/ChangeLog b/ChangeLog index d2717377b95..9e5fe24708f 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11652,6 +11652,17 @@ * drivers/wireless/nrf24l01.c: Fix backward calculation of relative frequency. Noted by Henry Zhang (2015-04-15). * drivers/sensors/h1750fvi.c: Add a character driver for Rohm Ambient - Light Sensor BH1750FVI. From Alan Carvalho de Assi (2016-04-15). + Light Sensor BH1750FVI. From Alan Carvalho de Assis (2016-04-15). * configs/stm32f4discovery: Integrate BH1750FVI driver in the - STM32F4Discovery board. From Alan Carvalho de Assi (2016-04-15). + STM32F4Discovery board. From Alan Carvalho de Assis (2016-04-15). + * drivers/mtd: Add MTD support for Micron N25Qxxx family of QSPI flash. + From Dave dev@ziggurat29.com (2016-04-17). + * arch/arm/src/stm32l: Add a QSPI driver. From Dave dev@ziggurat29.com + (2016-04-18). + * configs/stm32l476vb-disco: Add support for QSPI based N25Qxxx flash. + From Dave dev@ziggurat29.com (2016-04-18). + * graphics/vnc: Add support for a VNC server. This logic is code + 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). + diff --git a/configs/samv71-xult/README.txt b/configs/samv71-xult/README.txt index 60d3b6c5131..1b9ff29e10b 100644 --- a/configs/samv71-xult/README.txt +++ b/configs/samv71-xult/README.txt @@ -2308,3 +2308,22 @@ Configuration sub-directories - Line spacing in the NxTerm window is too much. This is probably a font-related issue too. + vnc: + + This is a special version of an NSH configuration. It has networking + and graphics enabled. It is configured to use the VNC server to provide + a remote desktop for use with VNC client on a PC. It includes the + graphics text at apps/examples/nximage. + + NOTES: + + 1. The RAMLOG is enabled so all debug output will go to the RAMLOG and + can be view using the NSH dmesg command. No debug output is enabled + in the default configuration, however. + + 2. Network confiration: IP address 10.0.0.2. The is easily changed + via 'make menuconfig'. The VNC server address is 10.0.0.2:5900. + + 3. The default (local) framebuffer configuration is 320x240 with 16-bit + RGB color. + diff --git a/configs/samv71-xult/vnc/Make.defs b/configs/samv71-xult/vnc/Make.defs new file mode 100644 index 00000000000..5185c94a9fb --- /dev/null +++ b/configs/samv71-xult/vnc/Make.defs @@ -0,0 +1,117 @@ +############################################################################ +# configs/samv71-xult/vnc/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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 = + diff --git a/configs/samv71-xult/vnc/defconfig b/configs/samv71-xult/vnc/defconfig new file mode 100644 index 00000000000..5e5f76362a8 --- /dev/null +++ b/configs/samv71-xult/vnc/defconfig @@ -0,0 +1,1379 @@ +# +# Automatically generated file; DO NOT EDIT. +# Nuttx/ Configuration +# + +# +# Build Setup +# +CONFIG_EXPERIMENTAL=y +# CONFIG_DEFAULT_SMALL is not set +# CONFIG_HOST_LINUX is not set +# CONFIG_HOST_OSX is not set +CONFIG_HOST_WINDOWS=y +# CONFIG_HOST_OTHER is not set +# CONFIG_WINDOWS_NATIVE is not set +CONFIG_WINDOWS_CYGWIN=y +# CONFIG_WINDOWS_MSYS is not set +# CONFIG_WINDOWS_OTHER is not set + +# +# Build Configuration +# +# CONFIG_APPS_DIR="../apps" +CONFIG_BUILD_FLAT=y +# CONFIG_BUILD_2PASS is not set + +# +# Binary Output Formats +# +# CONFIG_RRLOAD_BINARY is not set +# CONFIG_INTELHEX_BINARY is not set +# CONFIG_MOTOROLA_SREC is not set +CONFIG_RAW_BINARY=y +# CONFIG_UBOOT_UIMAGE is not set + +# +# Customize Header Files +# +# CONFIG_ARCH_STDINT_H is not set +# CONFIG_ARCH_STDBOOL_H is not set +# CONFIG_ARCH_MATH_H is not set +# CONFIG_ARCH_FLOAT_H is not set +# CONFIG_ARCH_STDARG_H is not set +# CONFIG_ARCH_DEBUG_H is not set + +# +# Debug Options +# +# CONFIG_DEBUG is not set +# CONFIG_ARCH_HAVE_HEAPCHECK is not set +CONFIG_ARCH_HAVE_STACKCHECK=y +# CONFIG_STACK_COLORATION is not set +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ARCH_HAVE_CUSTOMOPT=y +# CONFIG_DEBUG_NOOPT is not set +# CONFIG_DEBUG_CUSTOMOPT is not set +CONFIG_DEBUG_FULLOPT=y + +# +# System Type +# +CONFIG_ARCH_ARM=y +# CONFIG_ARCH_AVR is not set +# CONFIG_ARCH_HC is not set +# CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_RGMP is not set +# CONFIG_ARCH_SH is not set +# CONFIG_ARCH_SIM is not set +# CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_Z16 is not set +# CONFIG_ARCH_Z80 is not set +CONFIG_ARCH="arm" + +# +# ARM Options +# +# CONFIG_ARCH_CHIP_A1X is not set +# CONFIG_ARCH_CHIP_C5471 is not set +# CONFIG_ARCH_CHIP_CALYPSO is not set +# CONFIG_ARCH_CHIP_DM320 is not set +# CONFIG_ARCH_CHIP_EFM32 is not set +# CONFIG_ARCH_CHIP_IMX1 is not set +# CONFIG_ARCH_CHIP_IMX6 is not set +# CONFIG_ARCH_CHIP_KINETIS is not set +# CONFIG_ARCH_CHIP_KL is not set +# CONFIG_ARCH_CHIP_LM is not set +# CONFIG_ARCH_CHIP_TIVA is not set +# CONFIG_ARCH_CHIP_LPC11XX is not set +# CONFIG_ARCH_CHIP_LPC17XX is not set +# CONFIG_ARCH_CHIP_LPC214X is not set +# CONFIG_ARCH_CHIP_LPC2378 is not set +# CONFIG_ARCH_CHIP_LPC31XX is not set +# CONFIG_ARCH_CHIP_LPC43XX is not set +# CONFIG_ARCH_CHIP_NUC1XX is not set +# CONFIG_ARCH_CHIP_SAMA5 is not set +# CONFIG_ARCH_CHIP_SAMD is not set +# CONFIG_ARCH_CHIP_SAML is not set +# CONFIG_ARCH_CHIP_SAM34 is not set +CONFIG_ARCH_CHIP_SAMV7=y +# CONFIG_ARCH_CHIP_STM32 is not set +# CONFIG_ARCH_CHIP_STM32F7 is not set +# CONFIG_ARCH_CHIP_STM32L4 is not set +# CONFIG_ARCH_CHIP_STR71X is not set +# CONFIG_ARCH_CHIP_TMS570 is not set +# CONFIG_ARCH_CHIP_MOXART is not set +# CONFIG_ARCH_ARM7TDMI is not set +# CONFIG_ARCH_ARM926EJS is not set +# CONFIG_ARCH_ARM920T is not set +# CONFIG_ARCH_CORTEXM0 is not set +# CONFIG_ARCH_CORTEXM3 is not set +# CONFIG_ARCH_CORTEXM4 is not set +CONFIG_ARCH_CORTEXM7=y +# CONFIG_ARCH_CORTEXA5 is not set +# CONFIG_ARCH_CORTEXA8 is not set +# CONFIG_ARCH_CORTEXA9 is not set +# CONFIG_ARCH_CORTEXR4 is not set +# CONFIG_ARCH_CORTEXR4F is not set +# CONFIG_ARCH_CORTEXR5 is not set +# CONFIG_ARCH_CORTEX5F is not set +# CONFIG_ARCH_CORTEXR7 is not set +# CONFIG_ARCH_CORTEXR7F is not set +CONFIG_ARCH_FAMILY="armv7-m" +CONFIG_ARCH_CHIP="samv7" +# CONFIG_ARM_TOOLCHAIN_IAR is not set +CONFIG_ARM_TOOLCHAIN_GNU=y +# CONFIG_ARMV7M_USEBASEPRI is not set +CONFIG_ARCH_HAVE_CMNVECTOR=y +CONFIG_ARMV7M_CMNVECTOR=y +CONFIG_ARMV7M_LAZYFPU=y +CONFIG_ARCH_HAVE_FPU=y +CONFIG_ARCH_HAVE_DPFPU=y +CONFIG_ARCH_FPU=y +CONFIG_ARCH_DPFPU=y +# CONFIG_ARCH_HAVE_TRUSTZONE is not set +CONFIG_ARM_HAVE_MPU_UNIFIED=y +# CONFIG_ARM_MPU is not set + +# +# ARMV7M Configuration Options +# +CONFIG_ARMV7M_HAVE_ICACHE=y +CONFIG_ARMV7M_HAVE_DCACHE=y +CONFIG_ARMV7M_ICACHE=y +CONFIG_ARMV7M_DCACHE=y +CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y +CONFIG_ARMV7M_HAVE_ITCM=y +CONFIG_ARMV7M_HAVE_DTCM=y +# CONFIG_ARMV7M_ITCM is not set +# CONFIG_ARMV7M_DTCM is not set +# CONFIG_ARMV7M_TOOLCHAIN_IARW is not set +# CONFIG_ARMV7M_TOOLCHAIN_ATOLLIC is not set +# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODEREDW is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYW is not set +# CONFIG_ARMV7M_TOOLCHAIN_DEVKITARM is not set +# CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL is not set +CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIW=y +# CONFIG_ARMV7M_TOOLCHAIN_RAISONANCE is not set +CONFIG_ARMV7M_HAVE_STACKCHECK=y +# CONFIG_ARMV7M_STACKCHECK is not set +# CONFIG_ARMV7M_ITMSYSLOG is not set +# CONFIG_SERIAL_TERMIOS is not set +CONFIG_SDIO_DMA=y +# CONFIG_SDIO_WIDTH_D1_ONLY is not set + +# +# SAMV7 Configuration Options +# +# CONFIG_ARCH_CHIP_SAME70Q19 is not set +# CONFIG_ARCH_CHIP_SAME70Q20 is not set +# CONFIG_ARCH_CHIP_SAME70Q21 is not set +# CONFIG_ARCH_CHIP_SAME70N19 is not set +# CONFIG_ARCH_CHIP_SAME70N20 is not set +# CONFIG_ARCH_CHIP_SAME70N21 is not set +# CONFIG_ARCH_CHIP_SAME70J19 is not set +# CONFIG_ARCH_CHIP_SAME70J20 is not set +# CONFIG_ARCH_CHIP_SAME70J21 is not set +# CONFIG_ARCH_CHIP_SAMV71Q19 is not set +# CONFIG_ARCH_CHIP_SAMV71Q20 is not set +CONFIG_ARCH_CHIP_SAMV71Q21=y +# CONFIG_ARCH_CHIP_SAMV71N19 is not set +# CONFIG_ARCH_CHIP_SAMV71N20 is not set +# CONFIG_ARCH_CHIP_SAMV71N21 is not set +# CONFIG_ARCH_CHIP_SAMV71J19 is not set +# CONFIG_ARCH_CHIP_SAMV71J20 is not set +# CONFIG_ARCH_CHIP_SAMV71J21 is not set +# CONFIG_ARCH_CHIP_SAME70 is not set +# CONFIG_ARCH_CHIP_SAME70Q is not set +# CONFIG_ARCH_CHIP_SAME70N is not set +# CONFIG_ARCH_CHIP_SAME70J is not set +CONFIG_ARCH_CHIP_SAMV71=y +CONFIG_ARCH_CHIP_SAMV71Q=y +# CONFIG_ARCH_CHIP_SAMV71N is not set +# CONFIG_ARCH_CHIP_SAMV71J is not set +# CONFIG_SAMV7_MCAN is not set +CONFIG_SAMV7_HAVE_MCAN1=y +CONFIG_SAMV7_HAVE_DAC1=y +CONFIG_SAMV7_HAVE_EBI=y +CONFIG_SAMV7_EMAC=y +CONFIG_SAMV7_HSMCI=y +CONFIG_SAMV7_HAVE_HSMCI0=y +# CONFIG_SAMV7_HAVE_ISI8 is not set +CONFIG_SAMV7_HAVE_MEDIALB=y +CONFIG_SAMV7_HAVE_SDRAMC=y +CONFIG_SAMV7_HAVE_SPI0=y +CONFIG_SAMV7_HAVE_SPI1=y +# CONFIG_SAMV7_QSPI_IS_SPI is not set +# CONFIG_SAMV7_SSC is not set +# CONFIG_SAMV7_HAVE_TC is not set +CONFIG_SAMV7_HAVE_TWIHS2=y +# CONFIG_SAMV7_HAVE_USBFS is not set +CONFIG_SAMV7_HAVE_USBHS=y +CONFIG_SAMV7_HAVE_USART0=y +CONFIG_SAMV7_HAVE_USART1=y +CONFIG_SAMV7_HAVE_USART2=y +# CONFIG_SAMV7_SPI is not set +# CONFIG_SAMV7_SPI_MASTER is not set +# CONFIG_SAMV7_SPI_SLAVE is not set + +# +# SAMV7 Peripheral Selection +# +# CONFIG_SAMV7_ACC is not set +# CONFIG_SAMV7_ADC is not set +# CONFIG_SAMV7_AFEC0 is not set +# CONFIG_SAMV7_AFEC1 is not set +# CONFIG_SAMV7_MCAN0 is not set +# CONFIG_SAMV7_MCAN1 is not set +# CONFIG_SAMV7_DAC0 is not set +# CONFIG_SAMV7_DAC1 is not set +# CONFIG_SAMV7_EBI is not set +CONFIG_SAMV7_EMAC0=y +CONFIG_SAMV7_XDMAC=y +CONFIG_SAMV7_HSMCI0=y +# CONFIG_SAMV7_ISI is not set +# CONFIG_SAMV7_MLB is not set +# CONFIG_SAMV7_PWM0 is not set +# CONFIG_SAMV7_PWM1 is not set +# CONFIG_SAMV7_QSPI is not set +# CONFIG_SAMV7_RTC is not set +# CONFIG_SAMV7_RTT is not set +# CONFIG_SAMV7_SDRAMC is not set +# CONFIG_SAMV7_SMC is not set +# CONFIG_SAMV7_SPI0 is not set +# CONFIG_SAMV7_SPI1 is not set +# CONFIG_SAMV7_SSC0 is not set +# CONFIG_SAMV7_TC0 is not set +# CONFIG_SAMV7_TC1 is not set +# CONFIG_SAMV7_TC2 is not set +# CONFIG_SAMV7_TC3 is not set +# CONFIG_SAMV7_TRNG is not set +CONFIG_SAMV7_TWIHS0=y +# CONFIG_SAMV7_TWIHS1 is not set +# CONFIG_SAMV7_TWIHS2 is not set +# CONFIG_SAMV7_UART0 is not set +# CONFIG_SAMV7_UART1 is not set +# CONFIG_SAMV7_UART2 is not set +CONFIG_SAMV7_UART3=y +# CONFIG_SAMV7_UART4 is not set +# CONFIG_SAMV7_USBDEVHS is not set +# CONFIG_SAMV7_USBHOSTHS is not set +# CONFIG_SAMV7_USART0 is not set +# CONFIG_SAMV7_USART1 is not set +# CONFIG_SAMV7_USART2 is not set +# CONFIG_SAMV7_WDT is not set +# CONFIG_SAMV7_RSWDT is not set +CONFIG_SAMV7_GPIO_IRQ=y +CONFIG_SAMV7_GPIOA_IRQ=y +CONFIG_SAMV7_GPIOB_IRQ=y +# CONFIG_SAMV7_GPIOC_IRQ is not set +CONFIG_SAMV7_GPIOD_IRQ=y +# CONFIG_SAMV7_GPIOE_IRQ is not set +# CONFIG_SAMV7_PROGMEM is not set + +# +# TWIHS device driver options +# +CONFIG_SAMV7_TWIHS0_FREQUENCY=100000 + +# +# HSMCI device driver options +# +# CONFIG_SAMV7_HSMCI_RDPROOF is not set +# CONFIG_SAMV7_HSMCI_WRPROOF is not set +# CONFIG_SAMV7_HSMCI_UNALIGNED is not set + +# +# EMAC device driver options +# +CONFIG_SAMV7_EMAC0_NRXBUFFERS=16 +CONFIG_SAMV7_EMAC0_NTXBUFFERS=8 +CONFIG_SAMV7_EMAC0_PHYADDR=1 +# CONFIG_SAMV7_EMAC0_PHYINIT is not set +# CONFIG_SAMV7_EMAC0_MII is not set +CONFIG_SAMV7_EMAC0_RMII=y +CONFIG_SAMV7_EMAC0_AUTONEG=y +CONFIG_SAMV7_EMAC0_PHYSR=30 +CONFIG_SAMV7_EMAC0_PHYSR_ALTCONFIG=y +CONFIG_SAMV7_EMAC0_PHYSR_ALTMODE=0x7 +CONFIG_SAMV7_EMAC0_PHYSR_10HD=0x1 +CONFIG_SAMV7_EMAC0_PHYSR_100HD=0x2 +CONFIG_SAMV7_EMAC0_PHYSR_10FD=0x5 +CONFIG_SAMV7_EMAC0_PHYSR_100FD=0x6 +CONFIG_SAMV7_EMAC0_ISETH0=y +# CONFIG_SAMV7_EMAC_PREALLOCATE is not set +# CONFIG_SAMV7_EMAC_NBC is not set + +# +# Architecture Options +# +# CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set +CONFIG_ARCH_DMA=y +CONFIG_ARCH_HAVE_IRQPRIO=y +# CONFIG_ARCH_L2CACHE is not set +# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set +# CONFIG_ARCH_HAVE_ADDRENV is not set +# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set +# CONFIG_ARCH_HAVE_MULTICPU is not set +CONFIG_ARCH_HAVE_VFORK=y +# CONFIG_ARCH_HAVE_MMU is not set +CONFIG_ARCH_HAVE_MPU=y +# CONFIG_ARCH_NAND_HWECC is not set +# CONFIG_ARCH_HAVE_EXTCLK is not set +# CONFIG_ARCH_HAVE_POWEROFF is not set +# CONFIG_ARCH_HAVE_RESET is not set +# CONFIG_ARCH_USE_MPU is not set +# CONFIG_ARCH_IRQPRIO is not set +CONFIG_ARCH_STACKDUMP=y +# CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_IDLE_CUSTOM is not set +CONFIG_ARCH_HAVE_RAMFUNCS=y +# CONFIG_ARCH_RAMFUNCS is not set +CONFIG_ARCH_HAVE_RAMVECTORS=y +# CONFIG_ARCH_RAMVECTORS is not set + +# +# Board Settings +# +CONFIG_BOARD_LOOPSPERMSEC=51262 +# CONFIG_ARCH_CALIBRATION is not set + +# +# Interrupt options +# +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y +# CONFIG_ARCH_HIPRI_INTERRUPT is not set + +# +# Boot options +# +# CONFIG_BOOT_RUNFROMEXTSRAM is not set +CONFIG_BOOT_RUNFROMFLASH=y +# CONFIG_BOOT_RUNFROMISRAM is not set +# CONFIG_BOOT_RUNFROMSDRAM is not set +# CONFIG_BOOT_COPYTORAM is not set + +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x20400000 +CONFIG_RAM_SIZE=393216 +# CONFIG_ARCH_HAVE_SDRAM is not set + +# +# Board Selection +# +CONFIG_ARCH_BOARD_SAMV71_XULT=y +# CONFIG_ARCH_BOARD_CUSTOM is not set +CONFIG_ARCH_BOARD="samv71-xult" + +# +# Common Board Options +# +CONFIG_ARCH_HAVE_LEDS=y +CONFIG_ARCH_LEDS=y +CONFIG_ARCH_HAVE_BUTTONS=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_HAVE_IRQBUTTONS=y +CONFIG_ARCH_IRQBUTTONS=y +CONFIG_NSH_MMCSDMINOR=0 +CONFIG_NSH_MMCSDSLOTNO=0 + +# +# Board-Specific Options +# +# CONFIG_SAMV71XULT_MXTXPLND is not set +CONFIG_LIB_BOARDCTL=y +# CONFIG_BOARDCTL_UNIQUEID is not set +# CONFIG_BOARDCTL_TSCTEST is not set +# CONFIG_BOARDCTL_ADCTEST is not set +# CONFIG_BOARDCTL_PWMTEST is not set +# CONFIG_BOARDCTL_GRAPHICS is not set +# CONFIG_BOARDCTL_IOCTL is not set + +# +# RTOS Features +# +CONFIG_DISABLE_OS_API=y +# CONFIG_DISABLE_POSIX_TIMERS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_DISABLE_SIGNALS is not set +# CONFIG_DISABLE_MQUEUE is not set +# CONFIG_DISABLE_ENVIRON is not set + +# +# Clocks and Timers +# +CONFIG_ARCH_HAVE_TICKLESS=y +# CONFIG_SCHED_TICKLESS is not set +CONFIG_USEC_PER_TICK=10000 +# CONFIG_SYSTEM_TIME64 is not set +# CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_JULIAN_TIME is not set +CONFIG_START_YEAR=2014 +CONFIG_START_MONTH=3 +CONFIG_START_DAY=10 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_PREALLOC_WDOGS=32 +CONFIG_WDOG_INTRESERVE=4 +CONFIG_PREALLOC_TIMERS=4 + +# +# Tasks and Scheduling +# +# CONFIG_SPINLOCK is not set +# CONFIG_INIT_NONE is not set +CONFIG_INIT_ENTRYPOINT=y +# CONFIG_INIT_FILEPATH is not set +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_RR_INTERVAL=200 +# CONFIG_SCHED_SPORADIC is not set +CONFIG_TASK_NAME_SIZE=31 +CONFIG_MAX_TASKS=16 +# CONFIG_SCHED_HAVE_PARENT is not set +CONFIG_SCHED_WAITPID=y + +# +# Pthread Options +# +# CONFIG_MUTEX_TYPES is not set +CONFIG_NPTHREAD_KEYS=4 + +# +# Performance Monitoring +# +# CONFIG_SCHED_CPULOAD is not set +# CONFIG_SCHED_INSTRUMENTATION is not set + +# +# Files and I/O +# +CONFIG_DEV_CONSOLE=y +# CONFIG_FDCLONE_DISABLE is not set +# CONFIG_FDCLONE_STDIO is not set +CONFIG_SDCLONE_DISABLE=y +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NAME_MAX=32 +# CONFIG_PRIORITY_INHERITANCE is not set + +# +# RTOS hooks +# +# CONFIG_BOARD_INITIALIZE is not set +# CONFIG_SCHED_STARTHOOK is not set +# CONFIG_SCHED_ATEXIT is not set +# CONFIG_SCHED_ONEXIT is not set +# CONFIG_SIG_EVTHREAD is not set + +# +# Signal Numbers +# +CONFIG_SIG_SIGUSR1=1 +CONFIG_SIG_SIGUSR2=2 +CONFIG_SIG_SIGALARM=3 +CONFIG_SIG_SIGCONDTIMEDOUT=16 +CONFIG_SIG_SIGWORK=17 + +# +# POSIX Message Queue Options +# +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_MQ_MAXMSGSIZE=32 +# CONFIG_MODULE is not set + +# +# Work queue support +# +CONFIG_SCHED_WORKQUEUE=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=224 +CONFIG_SCHED_HPWORKPERIOD=50000 +CONFIG_SCHED_HPWORKSTACKSIZE=2048 +# CONFIG_SCHED_LPWORK is not set + +# +# Stack and heap information +# +CONFIG_IDLETHREAD_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=2048 +CONFIG_PTHREAD_STACK_MIN=256 +CONFIG_PTHREAD_STACK_DEFAULT=2048 +# CONFIG_LIB_SYSCALL is not set + +# +# Device Drivers +# +CONFIG_DISABLE_POLL=y +CONFIG_DEV_NULL=y +# CONFIG_DEV_ZERO is not set +# CONFIG_DEV_LOOP is not set + +# +# Buffering +# +# CONFIG_DRVR_WRITEBUFFER is not set +# CONFIG_DRVR_READAHEAD is not set +# CONFIG_RAMDISK is not set +# CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set +# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set +# CONFIG_PWM is not set +# CONFIG_ARCH_HAVE_I2CRESET is not set +CONFIG_I2C=y +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_POLLED is not set +# CONFIG_I2C_TRACE is not set +CONFIG_I2C_DRIVER=y +CONFIG_SPI=y +# CONFIG_SPI_SLAVE is not set +CONFIG_SPI_EXCHANGE=y +# CONFIG_SPI_CMDDATA is not set +# CONFIG_SPI_CALLBACK is not set +# CONFIG_SPI_BITBANG is not set +# CONFIG_SPI_HWFEATURES is not set +# CONFIG_SPI_CRCGENERATION is not set +# CONFIG_I2S is not set + +# +# Timer Driver Support +# +# CONFIG_TIMER is not set +# CONFIG_RTC is not set +# CONFIG_WATCHDOG is not set +# CONFIG_TIMERS_CS2100CP is not set +# CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set +# CONFIG_VIDEO_DEVICES is not set +# CONFIG_BCH is not set +# CONFIG_INPUT is not set +# CONFIG_IOEXPANDER is not set +# CONFIG_LCD is not set + +# +# LED Support +# +# CONFIG_USERLED is not set +# CONFIG_RGBLED is not set +# CONFIG_PCA9635PW is not set +CONFIG_MMCSD=y +CONFIG_MMCSD_NSLOTS=1 +# CONFIG_MMCSD_READONLY is not set +CONFIG_MMCSD_MULTIBLOCK_DISABLE=y +# CONFIG_MMCSD_MMCSUPPORT is not set +CONFIG_MMCSD_HAVECARDDETECT=y +# CONFIG_MMCSD_SPI is not set +CONFIG_ARCH_HAVE_SDIO=y +# CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE is not set +CONFIG_MMCSD_SDIO=y +# CONFIG_SDIO_PREFLIGHT is not set +# CONFIG_SDIO_MUXBUS is not set +CONFIG_SDIO_BLOCKSETUP=y +# CONFIG_MODEM is not set +CONFIG_MTD=y + +# +# MTD Configuration +# +# CONFIG_MTD_PARTITION is not set +# CONFIG_MTD_SECT512 is not set +# CONFIG_MTD_BYTE_WRITE is not set +# CONFIG_MTD_PROGMEM is not set +CONFIG_MTD_CONFIG=y +# CONFIG_MTD_CONFIG_RAM_CONSOLIDATE is not set +CONFIG_MTD_CONFIG_ERASEDVALUE=0xff + +# +# MTD Device Drivers +# +# CONFIG_MTD_NAND is not set +# CONFIG_RAMMTD is not set +# CONFIG_FILEMTD is not set +CONFIG_MTD_AT24XX=y +# CONFIG_AT24XX_MULTI is not set +CONFIG_AT24XX_SIZE=2 +CONFIG_AT24XX_ADDR=0x57 +CONFIG_AT24XX_EXTENDED=y +CONFIG_AT24XX_EXTSIZE=160 +CONFIG_AT24XX_FREQUENCY=100000 +CONFIG_MTD_AT25=y +CONFIG_AT25_SPIMODE=0 +CONFIG_AT25_SPIFREQUENCY=20000000 +# CONFIG_MTD_AT45DB is not set +# CONFIG_MTD_M25P is not set +# CONFIG_MTD_S25FL1 is not set +# CONFIG_MTD_N25QXXX is not set +# CONFIG_MTD_SMART is not set +# CONFIG_MTD_RAMTRON is not set +# CONFIG_MTD_SST25 is not set +# CONFIG_MTD_SST25XX is not set +# CONFIG_MTD_SST39FV is not set +# CONFIG_MTD_W25 is not set +# CONFIG_EEPROM is not set +CONFIG_NETDEVICES=y + +# +# General Ethernet MAC Driver Options +# +# CONFIG_NETDEV_LOOPBACK is not set +CONFIG_NETDEV_TELNET=y +CONFIG_TELNET_RXBUFFER_SIZE=256 +CONFIG_TELNET_TXBUFFER_SIZE=256 +# CONFIG_NETDEV_MULTINIC is not set +CONFIG_ARCH_HAVE_NETDEV_STATISTICS=y +CONFIG_NETDEV_STATISTICS=y +# CONFIG_NETDEV_LATEINIT is not set + +# +# External Ethernet MAC Device Support +# +# CONFIG_NET_DM90x0 is not set +# CONFIG_NET_CS89x0 is not set +# CONFIG_ENC28J60 is not set +# CONFIG_ENCX24J600 is not set +# CONFIG_NET_E1000 is not set +# CONFIG_NET_SLIP is not set +# CONFIG_NET_FTMAC100 is not set +# CONFIG_NET_VNET is not set + +# +# External Ethernet PHY Device Support +# +CONFIG_ARCH_PHY_INTERRUPT=y +# CONFIG_ETH0_PHY_NONE is not set +# CONFIG_ETH0_PHY_AM79C874 is not set +# CONFIG_ETH0_PHY_KS8721 is not set +# CONFIG_ETH0_PHY_KSZ8041 is not set +# CONFIG_ETH0_PHY_KSZ8051 is not set +CONFIG_ETH0_PHY_KSZ8061=y +# CONFIG_ETH0_PHY_KSZ8081 is not set +# CONFIG_ETH0_PHY_KSZ90x1 is not set +# CONFIG_ETH0_PHY_DP83848C is not set +# CONFIG_ETH0_PHY_LAN8720 is not set +# CONFIG_ETH0_PHY_LAN8740 is not set +# CONFIG_ETH0_PHY_LAN8740A is not set +# CONFIG_ETH0_PHY_LAN8742A is not set +# CONFIG_ETH0_PHY_DM9161 is not set +# CONFIG_PIPES is not set +# CONFIG_PM is not set +# CONFIG_POWER is not set +# CONFIG_SENSORS is not set +# CONFIG_SERCOMM_CONSOLE is not set +CONFIG_SERIAL=y +# CONFIG_DEV_LOWCONSOLE is not set +# CONFIG_16550_UART is not set +# CONFIG_ARCH_HAVE_UART is not set +# CONFIG_ARCH_HAVE_UART0 is not set +# CONFIG_ARCH_HAVE_UART1 is not set +# CONFIG_ARCH_HAVE_UART2 is not set +CONFIG_ARCH_HAVE_UART3=y +# CONFIG_ARCH_HAVE_UART4 is not set +# CONFIG_ARCH_HAVE_UART5 is not set +# CONFIG_ARCH_HAVE_UART6 is not set +# CONFIG_ARCH_HAVE_UART7 is not set +# CONFIG_ARCH_HAVE_UART8 is not set +# CONFIG_ARCH_HAVE_SCI0 is not set +# CONFIG_ARCH_HAVE_SCI1 is not set +# CONFIG_ARCH_HAVE_USART0 is not set +# CONFIG_ARCH_HAVE_USART1 is not set +# CONFIG_ARCH_HAVE_USART2 is not set +# CONFIG_ARCH_HAVE_USART3 is not set +# CONFIG_ARCH_HAVE_USART4 is not set +# CONFIG_ARCH_HAVE_USART5 is not set +# CONFIG_ARCH_HAVE_USART6 is not set +# CONFIG_ARCH_HAVE_USART7 is not set +# CONFIG_ARCH_HAVE_USART8 is not set +# CONFIG_ARCH_HAVE_OTHER_UART is not set + +# +# USART Configuration +# +CONFIG_MCU_SERIAL=y +CONFIG_STANDARD_SERIAL=y +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set +# CONFIG_SERIAL_DMA is not set +CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y +CONFIG_UART3_SERIAL_CONSOLE=y +# CONFIG_OTHER_SERIAL_CONSOLE is not set +# CONFIG_NO_SERIAL_CONSOLE is not set + +# +# UART3 Configuration +# +CONFIG_UART3_RXBUFSIZE=256 +CONFIG_UART3_TXBUFSIZE=256 +CONFIG_UART3_BAUD=115200 +CONFIG_UART3_BITS=8 +CONFIG_UART3_PARITY=0 +CONFIG_UART3_2STOP=0 +# CONFIG_UART3_IFLOWCONTROL is not set +# CONFIG_UART3_OFLOWCONTROL is not set +# CONFIG_UART3_DMA is not set +# CONFIG_USBDEV is not set +# CONFIG_USBHOST is not set +# CONFIG_DRIVERS_WIRELESS is not set + +# +# System Logging Device Options +# + +# +# System Logging +# +CONFIG_RAMLOG=y +CONFIG_RAMLOG_SYSLOG=y +# CONFIG_RAMLOG_CONSOLE is not set +CONFIG_RAMLOG_BUFSIZE=1024 +# CONFIG_RAMLOG_CRLF is not set +CONFIG_RAMLOG_NONBLOCKING=y +# CONFIG_SYSLOG_CONSOLE is not set + +# +# Networking Support +# +CONFIG_ARCH_HAVE_NET=y +CONFIG_ARCH_HAVE_PHY=y +CONFIG_NET=y +CONFIG_NET_NOINTS=y +# CONFIG_NET_PROMISCUOUS is not set + +# +# Driver buffer configuration +# +# CONFIG_NET_MULTIBUFFER is not set +CONFIG_NET_ETH_MTU=590 +CONFIG_NET_ETH_TCP_RECVWNDO=536 +CONFIG_NET_GUARDSIZE=2 + +# +# Data link support +# +# CONFIG_NET_MULTILINK is not set +# CONFIG_NET_USER_DEVFMT is not set +CONFIG_NET_ETHERNET=y +# CONFIG_NET_LOOPBACK is not set +# CONFIG_NET_TUN is not set + +# +# Network Device Operations +# +CONFIG_NETDEV_PHY_IOCTL=y + +# +# Internet Protocol Selection +# +CONFIG_NET_IPv4=y +# CONFIG_NET_IPv6 is not set + +# +# Socket Support +# +CONFIG_NSOCKET_DESCRIPTORS=8 +CONFIG_NET_NACTIVESOCKETS=16 +CONFIG_NET_SOCKOPTS=y +# CONFIG_NET_SOLINGER is not set + +# +# Raw Socket Support +# +# CONFIG_NET_PKT is not set + +# +# Unix Domain Socket Support +# +# CONFIG_NET_LOCAL is not set + +# +# TCP/IP Networking +# +CONFIG_NET_TCP=y +# CONFIG_NET_TCPURGDATA is not set +# CONFIG_NET_TCP_REASSEMBLY is not set +CONFIG_NET_TCP_CONNS=8 +CONFIG_NET_MAX_LISTENPORTS=20 +CONFIG_NET_TCP_READAHEAD=y +CONFIG_NET_TCP_WRITE_BUFFERS=y +CONFIG_NET_TCP_NWRBCHAINS=8 +CONFIG_NET_TCP_RECVDELAY=0 +CONFIG_NET_TCPBACKLOG=y +# CONFIG_NET_SENDFILE is not set + +# +# UDP Networking +# +# CONFIG_NET_UDP is not set + +# +# ICMP Networking Support +# +CONFIG_NET_ICMP=y +CONFIG_NET_ICMP_PING=y + +# +# IGMPv2 Client Support +# +# CONFIG_NET_IGMP is not set + +# +# ARP Configuration +# +CONFIG_NET_ARP=y +CONFIG_NET_ARPTAB_SIZE=16 +CONFIG_NET_ARP_MAXAGE=120 +# CONFIG_NET_ARP_IPIN is not set +CONFIG_NET_ARP_SEND=y +CONFIG_ARP_SEND_MAXTRIES=5 +CONFIG_ARP_SEND_DELAYMSEC=20 + +# +# Network I/O Buffer Support +# +CONFIG_NET_IOB=y +CONFIG_IOB_NBUFFERS=36 +CONFIG_IOB_BUFSIZE=196 +CONFIG_IOB_NCHAINS=8 +CONFIG_IOB_THROTTLE=8 +# CONFIG_NET_ARCH_INCR32 is not set +# CONFIG_NET_ARCH_CHKSUM is not set +CONFIG_NET_STATISTICS=y + +# +# Routing Table Configuration +# +# CONFIG_NET_ROUTE is not set +CONFIG_NET_HOSTNAME="SAMV71-XULT" + +# +# Crypto API +# +# CONFIG_CRYPTO is not set + +# +# File Systems +# + +# +# File system configuration +# +# CONFIG_DISABLE_MOUNTPOINT is not set +# CONFIG_FS_AUTOMOUNTER is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +CONFIG_FS_READABLE=y +CONFIG_FS_WRITABLE=y +# CONFIG_FS_NAMED_SEMAPHORES is not set +CONFIG_FS_MQUEUE_MPATH="/var/mqueue" +# CONFIG_FS_RAMMAP is not set +CONFIG_FS_FAT=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_MAXFNAME=32 +# CONFIG_FS_FATTIME is not set +# CONFIG_FAT_FORCE_INDIRECT is not set +# CONFIG_FAT_DMAMEMORY is not set +# CONFIG_FAT_DIRECT_RETRY is not set +# CONFIG_FS_NXFFS is not set +# CONFIG_FS_ROMFS is not set +# CONFIG_FS_TMPFS is not set +# CONFIG_FS_SMARTFS is not set +# CONFIG_FS_BINFS is not set +CONFIG_FS_PROCFS=y +# CONFIG_FS_PROCFS_REGISTER is not set + +# +# Exclude individual procfs entries +# +# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set +# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set +# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set +# CONFIG_FS_PROCFS_EXCLUDE_NET is not set +# CONFIG_FS_PROCFS_EXCLUDE_MTD is not set +# CONFIG_FS_UNIONFS is not set + +# +# System Logging +# +CONFIG_SYSLOG=y +# CONFIG_SYSLOG_TIMESTAMP is not set +# CONFIG_SYSLOG_CHAR is not set + +# +# Graphics Support +# +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_8BPP is not set +# CONFIG_NX_DISABLE_16BPP is not set +# CONFIG_NX_DISABLE_24BPP is not set +CONFIG_NX_DISABLE_32BPP=y + +# +# Input Devices +# +CONFIG_NX_XYINPUT=y +# CONFIG_NX_XYINPUT_NONE is not set +CONFIG_NX_XYINPUT_MOUSE=y +# CONFIG_NX_XYINPUT_TOUCHSCREEN is not set +CONFIG_NX_KBD=y + +# +# Framed Window Borders +# +CONFIG_NXTK_BORDERWIDTH=4 +CONFIG_NXTK_DEFAULT_BORDERCOLORS=y +# CONFIG_NXTK_AUTORAISE is not set + +# +# Font Selections +# +CONFIG_NXFONTS_CHARBITS=7 +# CONFIG_NXFONT_MONO5X8 is not set +# CONFIG_NXFONT_SANS17X22 is not set +# CONFIG_NXFONT_SANS20X26 is not set +# CONFIG_NXFONT_SANS23X27 is not set +# CONFIG_NXFONT_SANS22X29 is not set +CONFIG_NXFONT_SANS28X37=y +# CONFIG_NXFONT_SANS39X48 is not set +# CONFIG_NXFONT_SANS17X23B is not set +# CONFIG_NXFONT_SANS20X27B is not set +# CONFIG_NXFONT_SANS22X29B is not set +# CONFIG_NXFONT_SANS28X37B is not set +# CONFIG_NXFONT_SANS40X49B is not set +# CONFIG_NXFONT_SERIF22X29 is not set +# CONFIG_NXFONT_SERIF29X37 is not set +# CONFIG_NXFONT_SERIF38X48 is not set +# CONFIG_NXFONT_SERIF22X28B is not set +# CONFIG_NXFONT_SERIF27X38B is not set +# CONFIG_NXFONT_SERIF38X49B is not set +# CONFIG_NXFONT_PIXEL_UNICODE is not set +# CONFIG_NXFONT_PIXEL_LCD_MACHINE is not set +# CONFIG_NXFONT_X11_MISC_FIXED_4X6 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_5X7 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_5X8 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_6X9 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_6X10 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_6X12 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_6X13 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_6X13B is not set +# CONFIG_NXFONT_X11_MISC_FIXED_6X13O is not set +# CONFIG_NXFONT_X11_MISC_FIXED_7X13 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_7X13B is not set +# CONFIG_NXFONT_X11_MISC_FIXED_7X13O is not set +# CONFIG_NXFONT_X11_MISC_FIXED_7X14 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_7X14B is not set +# CONFIG_NXFONT_X11_MISC_FIXED_8X13 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_8X13B is not set +# CONFIG_NXFONT_X11_MISC_FIXED_8X13O is not set +# CONFIG_NXFONT_X11_MISC_FIXED_9X15 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_9X15B is not set +# CONFIG_NXFONT_X11_MISC_FIXED_9X18 is not set +# CONFIG_NXFONT_X11_MISC_FIXED_9X18B is not set +# CONFIG_NXFONT_X11_MISC_FIXED_10X20 is not set +# CONFIG_NXTERM is not set + +# +# NX Multi-user only options +# +# CONFIG_NX_MULTIUSER is not set +CONFIG_VNCSERVER=y +CONFIG_VNCSERVER_PROTO3p3=y +# CONFIG_VNCSERVER_PROTO3p8 is not set +CONFIG_VNCSERVER_NDISPLAYS=1 +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_RGB32 is not set +CONFIG_VNCSERVER_SCREENWIDTH=320 +CONFIG_VNCSERVER_SCREENHEIGHT=240 +CONFIG_VNCSERVER_NUPDATES=48 +CONFIG_VNCSERVER_UPDATE_BUFSIZE=4096 +CONFIG_VNCSERVER_INBUFFER_SIZE=80 +# CONFIG_VNCCLIENT is not set + +# +# Memory Management +# +# CONFIG_MM_SMALL is not set +CONFIG_MM_REGIONS=1 +# CONFIG_ARCH_HAVE_HEAP2 is not set +# CONFIG_GRAN is not set + +# +# Audio Support +# +# CONFIG_AUDIO is not set + +# +# Wireless Support +# +# CONFIG_WIRELESS is not set + +# +# Binary Loader +# +# CONFIG_BINFMT_DISABLE is not set +# CONFIG_BINFMT_EXEPATH is not set +# CONFIG_NXFLAT is not set +# CONFIG_ELF is not set +CONFIG_BUILTIN=y +# CONFIG_PIC is not set +# CONFIG_SYMTAB_ORDEREDBYNAME is not set + +# +# Library Routines +# + +# +# Standard C Library Options +# +CONFIG_STDIO_BUFFER_SIZE=64 +CONFIG_STDIO_LINEBUFFER=y +CONFIG_NUNGET_CHARS=2 +CONFIG_LIB_HOMEDIR="/" +# CONFIG_LIBM is not set +# CONFIG_NOPRINTF_FIELDWIDTH is not set +# CONFIG_LIBC_FLOATINGPOINT is not set +CONFIG_LIBC_LONG_LONG=y +# CONFIG_LIBC_IOCTL_VARIADIC is not set +CONFIG_LIB_RAND_ORDER=1 +# CONFIG_EOL_IS_CR is not set +# CONFIG_EOL_IS_LF is not set +# CONFIG_EOL_IS_BOTH_CRLF is not set +CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_LIBC_EXECFUNCS is not set +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +# CONFIG_LIBC_STRERROR is not set +# CONFIG_LIBC_PERROR_STDOUT is not set +CONFIG_LIBC_TMPDIR="/tmp" +CONFIG_LIBC_MAX_TMPFILE=32 +CONFIG_ARCH_LOWPUTC=y +# CONFIG_LIBC_LOCALTIME is not set +# CONFIG_TIME_EXTENDED is not set +CONFIG_LIB_SENDFILE_BUFSIZE=512 +# CONFIG_ARCH_ROMGETC is not set +# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set +CONFIG_ARCH_HAVE_TLS=y +# CONFIG_TLS is not set +CONFIG_LIBC_NETDB=y +# CONFIG_NETDB_HOSTFILE is not set + +# +# Non-standard Library Support +# +# CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set + +# +# Basic CXX Support +# +# CONFIG_C99_BOOL8 is not set +# CONFIG_HAVE_CXX is not set + +# +# Application Configuration +# + +# +# Built-In Applications +# +CONFIG_BUILTIN_PROXY_STACKSIZE=1024 + +# +# CAN Utilities +# + +# +# Examples +# +# CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CHAT is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set +# CONFIG_EXAMPLES_CPUHOG is not set +# CONFIG_EXAMPLES_DHCPD is not set +# CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FSTEST is not set +# CONFIG_EXAMPLES_FTPC is not set +# CONFIG_EXAMPLES_FTPD is not set +# CONFIG_EXAMPLES_HELLO is not set +# CONFIG_EXAMPLES_JSON is not set +# CONFIG_EXAMPLES_HIDKBD is not set +# CONFIG_EXAMPLES_KEYPADTEST is not set +# CONFIG_EXAMPLES_IGMP is not set +# CONFIG_EXAMPLES_MEDIA is not set +# CONFIG_EXAMPLES_MM is not set +# CONFIG_EXAMPLES_MODBUS is not set +# CONFIG_EXAMPLES_MOUNT is not set +# CONFIG_EXAMPLES_NETTEST is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set +CONFIG_EXAMPLES_NSH=y +# CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set +# CONFIG_EXAMPLES_NXTERM is not set +# CONFIG_EXAMPLES_NXFFS is not set +# CONFIG_EXAMPLES_NXHELLO is not set +CONFIG_EXAMPLES_NXIMAGE=y +CONFIG_EXAMPLES_NXIMAGE_VPLANE=0 +CONFIG_EXAMPLES_NXIMAGE_DEVNO=0 +CONFIG_EXAMPLES_NXIMAGE_BPP=16 +# CONFIG_EXAMPLES_NXIMAGE_XSCALEp5 is not set +CONFIG_EXAMPLES_NXIMAGE_XSCALE1p0=y +# CONFIG_EXAMPLES_NXIMAGE_XSCALE1p5 is not set +# CONFIG_EXAMPLES_NXIMAGE_XSCALE2p0 is not set +# CONFIG_EXAMPLES_NXIMAGE_YSCALEp5 is not set +CONFIG_EXAMPLES_NXIMAGE_YSCALE1p0=y +# CONFIG_EXAMPLES_NXIMAGE_YSCALE1p5 is not set +# CONFIG_EXAMPLES_NXIMAGE_YSCALE2p0 is not set +# CONFIG_EXAMPLES_NXLINES is not set +# CONFIG_EXAMPLES_NXTEXT is not set +# CONFIG_EXAMPLES_OSTEST is not set +# CONFIG_EXAMPLES_PCA9635 is not set +# CONFIG_EXAMPLES_PIPE is not set +# CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set +# CONFIG_EXAMPLES_RGBLED is not set +# CONFIG_EXAMPLES_RGMP is not set +# CONFIG_EXAMPLES_SENDMAIL is not set +# CONFIG_EXAMPLES_SERIALBLASTER is not set +# CONFIG_EXAMPLES_SERIALRX is not set +# CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART_TEST is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_SMP is not set +# CONFIG_EXAMPLES_TCPECHO is not set +# CONFIG_EXAMPLES_TELNETD is not set +# CONFIG_EXAMPLES_TIFF is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_EXAMPLES_WEBSERVER is not set +# CONFIG_EXAMPLES_USBSERIAL is not set +# CONFIG_EXAMPLES_USBTERM is not set +# CONFIG_EXAMPLES_WATCHDOG is not set + +# +# File System Utilities +# +# CONFIG_FSUTILS_INIFILE is not set +# CONFIG_FSUTILS_PASSWD is not set + +# +# GPS Utilities +# +# CONFIG_GPSUTILS_MINMEA_LIB is not set + +# +# Graphics Support +# +# CONFIG_TIFF is not set +# CONFIG_GRAPHICS_TRAVELER is not set + +# +# Interpreters +# +# CONFIG_INTERPRETERS_BAS is not set +# CONFIG_INTERPRETERS_FICL is not set +# CONFIG_INTERPRETERS_PCODE is not set +# CONFIG_INTERPRETERS_MICROPYTHON is not set + +# +# FreeModBus +# +# CONFIG_MODBUS is not set + +# +# Network Utilities +# +# CONFIG_NETUTILS_CODECS is not set +# CONFIG_NETUTILS_FTPC is not set +# CONFIG_NETUTILS_JSON is not set +# CONFIG_NETUTILS_SMTP is not set +CONFIG_NETUTILS_TELNETD=y +CONFIG_NETUTILS_NETLIB=y +CONFIG_NETUTILS_WEBCLIENT=y +CONFIG_NSH_WGET_USERAGENT="NuttX/6.xx.x (; http://www.nuttx.org/)" +CONFIG_WEBCLIENT_TIMEOUT=10 +# CONFIG_NETUTILS_WEBSERVER is not set +# CONFIG_NETUTILS_XMLRPC is not set + +# +# NSH Library +# +CONFIG_NSH_LIBRARY=y +CONFIG_NSH_MOTD=y +# CONFIG_NSH_PLATFORM_MOTD is not set +CONFIG_NSH_MOTD_STRING="VNC Server at 10.0.0.2:5900" + +# +# Command Line Configuration +# +CONFIG_NSH_READLINE=y +# CONFIG_NSH_CLE is not set +CONFIG_NSH_LINELEN=64 +# CONFIG_NSH_DISABLE_SEMICOLON is not set +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_MAXARGUMENTS=6 +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_NESTDEPTH=3 +# CONFIG_NSH_DISABLEBG is not set +CONFIG_NSH_BUILTIN_APPS=y + +# +# Disable Individual commands +# +# CONFIG_NSH_DISABLE_ADDROUTE is not set +# CONFIG_NSH_DISABLE_ARP is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_CMP is not set +CONFIG_NSH_DISABLE_DATE=y +# CONFIG_NSH_DISABLE_DD is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_DELROUTE is not set +# CONFIG_NSH_DISABLE_DIRNAME is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_IFUPDOWN is not set +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOSETUP is not set +CONFIG_NSH_DISABLE_LOSMART=y +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MKFIFO is not set +# CONFIG_NSH_DISABLE_MKRD is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_MW is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PING is not set +# CONFIG_NSH_DISABLE_PUT is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SH is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_NSH_DISABLE_WGET is not set +# CONFIG_NSH_DISABLE_XD is not set + +# +# Configure Command Options +# +# CONFIG_NSH_CMDOPT_DF_H is not set +CONFIG_NSH_CODECS_BUFSIZE=128 +CONFIG_NSH_CMDOPT_HEXDUMP=y +CONFIG_NSH_PROC_MOUNTPOINT="/proc" +CONFIG_NSH_FILEIOSIZE=512 + +# +# Scripting Support +# +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_LOOPS is not set + +# +# Console Configuration +# +CONFIG_NSH_CONSOLE=y +CONFIG_NSH_ARCHINIT=y + +# +# Networking Configuration +# +CONFIG_NSH_NETINIT_THREAD=y +CONFIG_NSH_NETINIT_THREAD_STACKSIZE=1568 +CONFIG_NSH_NETINIT_THREAD_PRIORITY=80 + +# +# IP Address Configuration +# + +# +# IPv4 Addresses +# +CONFIG_NSH_IPADDR=0x0a000002 +CONFIG_NSH_DRIPADDR=0x0a000001 +CONFIG_NSH_NETMASK=0xffffff00 +# CONFIG_NSH_NOMAC is not set +CONFIG_NSH_MAX_ROUNDTRIP=20 + +# +# Telnet Configuration +# +CONFIG_NSH_TELNET=y +CONFIG_NSH_TELNETD_PORT=23 +CONFIG_NSH_TELNETD_DAEMONPRIO=100 +CONFIG_NSH_TELNETD_DAEMONSTACKSIZE=2048 +CONFIG_NSH_TELNETD_CLIENTPRIO=100 +CONFIG_NSH_TELNETD_CLIENTSTACKSIZE=2048 +CONFIG_NSH_IOBUFFER_SIZE=512 +# CONFIG_NSH_LOGIN is not set +# CONFIG_NSH_CONSOLE_LOGIN is not set +# CONFIG_NSH_TELNET_LOGIN is not set + +# +# NxWidgets/NxWM +# + +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set + +# +# System Libraries and NSH Add-Ons +# +# CONFIG_SYSTEM_FREE is not set +# CONFIG_SYSTEM_CLE is not set +# CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_INSTALL is not set +# CONFIG_SYSTEM_FLASH_ERASEALL is not set +# CONFIG_SYSTEM_HEX2BIN is not set +# CONFIG_SYSTEM_I2CTOOL is not set +# CONFIG_SYSTEM_HEXED is not set +# CONFIG_SYSTEM_NETDB is not set +# CONFIG_SYSTEM_RAMTEST is not set +CONFIG_READLINE_HAVE_EXTMATCH=y +CONFIG_SYSTEM_READLINE=y +CONFIG_READLINE_ECHO=y +# CONFIG_READLINE_TABCOMPLETION is not set +# CONFIG_READLINE_CMD_HISTORY is not set +# CONFIG_SYSTEM_MDIO is not set +# CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_VI is not set +# CONFIG_SYSTEM_UBLOXMODEM is not set +# CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/samv71-xult/vnc/setenv.sh b/configs/samv71-xult/vnc/setenv.sh new file mode 100644 index 00000000000..873796c9b0e --- /dev/null +++ b/configs/samv71-xult/vnc/setenv.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# configs/samv7-xult/vnc/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# 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}" diff --git a/graphics/Kconfig b/graphics/Kconfig index 40344d6ef74..02e02052299 100644 --- a/graphics/Kconfig +++ b/graphics/Kconfig @@ -745,4 +745,7 @@ config NXSTART_VPLANE endif # NX_NXSTART endif # NX_MULTIUSER + +source "graphics/vnc/Kconfig" + endif # NX diff --git a/graphics/Makefile b/graphics/Makefile index a8111002329..f23072a75c0 100644 --- a/graphics/Makefile +++ b/graphics/Makefile @@ -50,6 +50,7 @@ include nxbe/Make.defs include nxmu/Make.defs include nxsu/Make.defs include nxterm/Make.defs +include vnc/Make.defs AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) diff --git a/graphics/README.txt b/graphics/README.txt index ab24d090d6c..3c61000cb15 100644 --- a/graphics/README.txt +++ b/graphics/README.txt @@ -112,6 +112,10 @@ nuttx/../NxWidgets The NxWidgets code is provided as a separate package located outside of the NuttX source tree (probably at this location). +graphics/vnc + The future home of the VNC Remote Frame Buffer (RFB) server and client + implementations. + Installing New Fonts ^^^^^^^^^^^^^^^^^^^^ @@ -295,6 +299,8 @@ CONFIG_NXTK_AUTORAISE CONFIG_NXFONTS_CHARBITS The number of bits in the character set. Current options are only 7 and 8. The default is 7. +CONFIG_VNCSERVER and CONFIG_VNCCLIENT + Enable the VNC RFB server and client, respecitively. Font Selections --------------- diff --git a/graphics/vnc/Kconfig b/graphics/vnc/Kconfig new file mode 100644 index 00000000000..fed2283d62d --- /dev/null +++ b/graphics/vnc/Kconfig @@ -0,0 +1,7 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +source "graphics/vnc/server/Kconfig" +source "graphics/vnc/client/Kconfig" diff --git a/graphics/vnc/Make.defs b/graphics/vnc/Make.defs new file mode 100644 index 00000000000..cd9866723c7 --- /dev/null +++ b/graphics/vnc/Make.defs @@ -0,0 +1,37 @@ +############################################################################ +# graphics/vnc/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +include vnc/server/Make.defs +include vnc/client/Make.defs diff --git a/graphics/vnc/client/Kconfig b/graphics/vnc/client/Kconfig new file mode 100644 index 00000000000..212cb5cce8e --- /dev/null +++ b/graphics/vnc/client/Kconfig @@ -0,0 +1,15 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig VNCCLIENT + bool "VNC client" + default n + depends on NET_TCP && !NX_LCDDRIVER && !VNC_SERVER && EXPERIMENTAL + ---help--- + Enable support for a VNC Remote Frame Buffer (RFB) client + +if VNCCLIENT + +endif # VNCCLIENT diff --git a/graphics/vnc/client/Make.defs b/graphics/vnc/client/Make.defs new file mode 100644 index 00000000000..03d6f5b5aee --- /dev/null +++ b/graphics/vnc/client/Make.defs @@ -0,0 +1,42 @@ +############################################################################ +# graphics/vnc/client/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_VNCCLIENT),y) + +DEPPATH += --dep-path vnc/client +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/vnc/client} +VPATH += :vnc/client + +endif diff --git a/graphics/vnc/server/Kconfig b/graphics/vnc/server/Kconfig new file mode 100644 index 00000000000..1a5ad3ad713 --- /dev/null +++ b/graphics/vnc/server/Kconfig @@ -0,0 +1,106 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig VNCSERVER + bool "VNC server" + default n + depends on NET_TCP && !NX_LCDDRIVER && EXPERIMENTAL + select NET_TCP_READAHEAD + select NX_UPDATE + ---help--- + Enable support for a VNC Remote Frame Buffer (RFB) server. + +if VNCSERVER + +choice + prompt "VNC server protocol" + default VNCSERVER_PROTO3p3 + +config VNCSERVER_PROTO3p3 + bool "Version 3.3" + +config VNCSERVER_PROTO3p8 + bool "Version 3.8" + depends on EXPERIMENTAL + +endchoice # VNC server protocol + +config VNCSERVER_NDISPLAYS + int "Number of displays" + default 1 + range 1 99 + ---help--- + Specifies the number of RFB displays supported by the server. + Normally this should be one. + +config VNCSERVER_PRIO + int "VNC server task priority" + default 100 + +config VNCSERVER_STACKSIZE + int "VNC server stack size" + default 2048 + +config VNCSERVER_UPDATER_PRIO + int "VNC updater thread priority" + default 100 + +config VNCSERVER_UPDATER_STACKSIZE + int "VNC updater thread stack size" + default 2048 + +choice + prompt "VNC color format" + default VNCSERVER_COLORFMT_RGB16 + +config VNCSERVER_COLORFMT_RGB16 + bool "RGB16 5:6:5" + +config VNCSERVER_COLORFMT_RGB32 + bool "RGB24 (32-bit) or RGB32 (w/tranparency)" + +endchoice # VNC color format + +config VNCSERVER_SCREENWIDTH + int "Framebuffer width (pixels)" + default 320 + +config VNCSERVER_SCREENHEIGHT + int "Framebuffer height (rows)" + default 240 + +config VNCSERVER_NUPDATES + int "Number of pre-allocate update structures" + default 48 + ---help--- + This setting provides the number of pre-allocated update structures + that will be used. Dynamic memory allocations are never made. In + the likely event that we run out of update structures, the graphics + subsystem will pause and wait for the next structures to be released. + + Overhead is 12-bytes per update structure. + +config VNCSERVER_UPDATE_BUFSIZE + int "Max update buffer size (bytes)" + default 4096 + ---help--- + A single buffer is pre-allocated for rendering updates. This + setting specifies the maximum in bytes of that update buffer. For + example, an update buffers of 32 pixels at 32-bits per pixel and + 32-rows would yield a buffer size of 4096. + +config VNCSERVER_KBDENCODE + bool "Encode keyboard input" + default n + depends on NXTERM_NXKBDIN + ---help--- + Use a special encoding of keyboard characters as defined in + include/nuttx/input/kbd_coded.h. + +config VNCSERVER_INBUFFER_SIZE + int "Input buffer size + default 80 + +endif # VNCSERVER diff --git a/graphics/vnc/server/Make.defs b/graphics/vnc/server/Make.defs new file mode 100644 index 00000000000..263be54df6e --- /dev/null +++ b/graphics/vnc/server/Make.defs @@ -0,0 +1,48 @@ +############################################################################ +# graphics/vnc/server/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_VNCSERVER),y) + +CSRCS += vnc_server.c vnc_negotiate.c vnc_updater.c vnc_receiver.c vnc_fbdev.c + +ifeq ($(CONFIG_NX_KBD),y) +CSRCS += vnc_keymap.c +endif + +DEPPATH += --dep-path vnc/server +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/vnc/server} +VPATH += :vnc/server + +endif diff --git a/graphics/vnc/server/vnc_fbdev.c b/graphics/vnc/server/vnc_fbdev.c new file mode 100644 index 00000000000..87fb91b84d8 --- /dev/null +++ b/graphics/vnc/server/vnc_fbdev.c @@ -0,0 +1,671 @@ +/**************************************************************************** + * graphics/vnc/server/vnc_fbdev.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "vnc_server.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure provides the frame buffer interface and also incapulates + * information about the frame buffer instances for each display. + */ + +struct vnc_fbinfo_s +{ + /* The publically visible frame buffer interface. This must appear first + * so that struct vnc_fbinfo_s is cast compatible with struct fb_vtable_s. + */ + + struct fb_vtable_s vtable; + + /* Our private per-display information */ + + bool initialized; /* True: This instance has been initialized */ + uint8_t display; /* Display number */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Get information about the video controller configuration and the + * configuration of each color plane. + */ + +static int up_getvideoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo); +static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo); + +/* The following are provided only if the video hardware supports RGB color + * mapping. + */ + +#ifdef CONFIG_FB_CMAP +static int up_getcmap(FAR struct fb_vtable_s *vtable, + FAR struct fb_cmap_s *cmap); +static int up_putcmap(FAR struct fb_vtable_s *vtable, + FAR const struct fb_cmap_s *cmap); +#endif + +/* The following are provided only if the video hardware supports a hardware + * cursor. + */ + +#ifdef CONFIG_FB_HWCURSOR +static int up_getcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_cursorattrib_s *attrib); +static int up_setcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_setcursor_s *setttings); +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Current cursor position */ + +#ifdef CONFIG_FB_HWCURSOR +static struct fb_cursorpos_s g_cpos; + +/* Current cursor size */ + +#ifdef CONFIG_FB_HWCURSORSIZE +static struct fb_cursorsize_s g_csize; +#endif +#endif + +/* The framebuffer objects, one for each configured display. */ + +static struct vnc_fbinfo_s g_fbinfo[RFB_MAX_DISPLAYS]; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Used to synchronize the server thread with the framebuffer driver. + * NOTE: This depends on the fact that all zero is correct initial state + * for the semaphores. + */ + +struct fb_startup_s g_fbstartup[RFB_MAX_DISPLAYS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getvideoinfo + ****************************************************************************/ + +static int up_getvideoinfo(FAR struct fb_vtable_s *vtable, + FAR struct fb_videoinfo_s *vinfo) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + + gvdbg("vtable=%p vinfo=%p\n", vtable, vinfo); + + DEBUGASSERT(fbinfo != NULL && vinfo != NULL); + if (fbinfo != NULL && vinfo != NULL) + { + session = vnc_find_session(fbinfo->display); + if (session == NULL || session->state != VNCSERVER_RUNNING) + { + gdbg("ERROR: session is not connected\n"); + return -ENOTCONN; + } + + /* Return the requested video info. We are committed to using the + * configured color format in the framebuffer, but performing color + * conversions on the fly for the remote framebuffer as necessary. + */ + + vinfo->fmt = RFB_COLORFMT; + vinfo->xres = CONFIG_VNCSERVER_SCREENWIDTH; + vinfo->yres = CONFIG_VNCSERVER_SCREENHEIGHT; + vinfo->nplanes = 1; + + return OK; + } + + gdbg("ERROR: Invalid arguments\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: up_getplaneinfo + ****************************************************************************/ + +static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, + FAR struct fb_planeinfo_s *pinfo) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + + gvdbg("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo); + + DEBUGASSERT(fbinfo != NULL && pinfo != NULL && planeno == 0); + if (fbinfo != NULL && pinfo != NULL && planeno == 0) + { + session = vnc_find_session(fbinfo->display); + if (session == NULL || session->state != VNCSERVER_RUNNING) + { + gdbg("ERROR: session is not connected\n"); + return -ENOTCONN; + } + + DEBUGASSERT(session->fb != NULL); + + /* Return the requested plane info. We are committed to using the + * configured bits-per-pixels in the framebuffer, but performing color + * conversions on the fly for the remote framebuffer as necessary. + */ + + pinfo->fbmem = (FAR void *)session->fb; + pinfo->fblen = RFB_SIZE; + pinfo->stride = RFB_STRIDE; + pinfo->display = fbinfo->display; + pinfo->bpp = RFB_BITSPERPIXEL; + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} + +/**************************************************************************** + * Name: up_getcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int up_getcmap(FAR struct fb_vtable_s *vtable, + FAR struct fb_cmap_s *cmap) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + int i; + + gvdbg("vtable=%p cmap=%p\n", vtable, cmap); + + DEBUGASSERT(fbinfo != NULL && cmap != NULL); + + if (fbinfo != NULL && cmap != NULL) + { + session = vnc_find_session(fbinfo->display); + if (session == NULL || session->state != VNCSERVER_RUNNING) + { + gdbg("ERROR: session is not connected\n"); + return -ENOTCONN; + } + + gvdbg("first=%d len=%d\n", vcmap->first, cmap->len); +#warning Missing logic + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: up_putcmap + ****************************************************************************/ + +#ifdef CONFIG_FB_CMAP +static int up_putcmap(FAR struct fb_vtable_s *vtable, FAR const struct fb_cmap_s *cmap) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + int i; + + gvdbg("vtable=%p cmap=%p\n", vtable, cmap); + + DEBUGASSERT(fbinfo != NULL && cmap != NULL); + + if (fbinfo != NULL && cmap != NULL) + { + session = vnc_find_session(fbinfo->display); + if (session == NULL || session->state != VNCSERVER_RUNNING) + { + gdbg("ERROR: session is not connected\n"); + return -ENOTCONN; + } + + gvdbg("first=%d len=%d\n", vcmap->first, cmap->len); +#warning Missing logic + + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: up_getcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int up_getcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_cursorattrib_s *attrib) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + int i; + + gvdbg("vtable=%p attrib=%p\n", vtable, attrib); + + DEBUGASSERT(fbinfo != NULL && attrib != NULL); + + if (fbinfo != NULL && attrib != NULL) + { + session = vnc_find_session(fbinfo->display); + if (session == NULL || session->state != VNCSERVER_RUNNING) + { + gdbg("ERROR: session is not connected\n"); + return -ENOTCONN; + } + +#warning Missing logic + + return OK; + } + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: up_setcursor + ****************************************************************************/ + +#ifdef CONFIG_FB_HWCURSOR +static int up_setcursor(FAR struct fb_vtable_s *vtable, + FAR struct fb_setcursor_s *settings) +{ + FAR struct vnc_fbinfo_s *fbinfo = (FAR struct vnc_fbinfo_s *)vtable; + FAR struct vnc_session_s *session; + int i; + + gvdbg("vtable=%p settings=%p\n", vtable, settings); + + DEBUGASSERT(fbinfo != NULL && settings != NULL); + + if (fbinfo != NULL && settings != NULL) + { + session = vnc_find_session(fbinfo->display); + if (session == NULL || session->state != VNCSERVER_RUNNING) + { + gdbg("ERROR: session is not connected\n"); + return -ENOTCONN; + } + + gvdbg("flags: %02x\n", settings->flags); + if ((settings->flags & FB_CUR_SETPOSITION) != 0) + { +#warning Missing logic + } + +#ifdef CONFIG_FB_HWCURSORSIZE + if ((settings->flags & FB_CUR_SETSIZE) != 0) + { +#warning Missing logic + } +#endif +#ifdef CONFIG_FB_HWCURSORIMAGE + if ((settings->flags & FB_CUR_SETIMAGE) != 0) + { +#warning Missing logic + } +#endif + return OK; + } + + gdbg("Returning EINVAL\n"); + return -EINVAL; +} +#endif + +/**************************************************************************** + * Name: vnc_wait_server + * + * Description: + * Wait for the server to be connected to the VNC client. We can do + * nothing until that connection is established. + * + * 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_server(int display) +{ + int errcode; + int result; + + /* 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 RUNNING state. + * The RUNNING state indicates that the server has started, it has + * established a connection with the VNC client, it is negotiated + * encodings and framebuffer characteristics, and it has started the + * updater thread. The server is now ready to recieve Client-to-Server + * messages and to perform remote framebuffer updates. + */ + + while (g_vnc_sessions[display] == NULL || + g_vnc_sessions[display]->state != VNCSERVER_RUNNING) + { + /* 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].fbsem) < 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; + } + } + + /* We were awakened. A result of -EBUSY means that the negotiation + * is not complete. Why would we be awakened in that case? Some + * counting semaphore screw-up? + */ + + result = g_fbstartup[display].result; + if (result != -EBUSY) + { +#ifdef CONFIG_DEBUG + if (result < 0) + { + DEBUGASSERT(g_vnc_sessions[display] == NULL); + gdbg("ERROR: VNC server startup failed: %d\n", result); + } + else + { + DEBUGASSERT(g_vnc_sessions[display] != NULL && + g_vnc_sessions[display]->state == VNCSERVER_RUNNING); + } +#endif + return result; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_fbinitialize + * + * Description: + * Initialize the framebuffer video hardware associated with the display. + * + * 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. + * + ****************************************************************************/ + +int up_fbinitialize(int display) +{ + FAR char *argv[2]; + char str[8]; + pid_t pid; + + /* 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 */ + + g_fbstartup[display].result = -EBUSY; + sem_reset(&g_fbstartup[display].fbsem, 0); + + if (g_vnc_sessions[display] != NULL) + { + 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; + } + } + + /* Wait for the VNC client to connect and for the RFB to be ready */ + + return vnc_wait_server(display); +} + +/**************************************************************************** + * Name: up_fbgetvplane + * + * Description: + * Return a a reference to the framebuffer object for the specified video + * plane of the specified plane. Many OSDs support multiple planes of video. + * + * Input parameters: + * display - In the case of hardware with multiple displays, this + * specifies the display. Normally this is zero. + * vplane - Identifies the plane being queried. + * + * Returned Value: + * A non-NULL pointer to the frame buffer access structure is returned on + * success; NULL is returned on any failure. + * + ****************************************************************************/ + +FAR struct fb_vtable_s *up_fbgetvplane(int display, int vplane) +{ + FAR struct vnc_session_s *session = vnc_find_session(display); + FAR struct vnc_fbinfo_s *fbinfo; + + /* Verify that the session is still valid */ + + if (session->state != VNCSERVER_RUNNING) + { + return NULL; + } + + if (vplane == 0) + { + /* Has the framebuffer information been initialized for this display? */ + + fbinfo = &g_fbinfo[display]; + if (!fbinfo->initialized) + { + fbinfo->vtable.getvideoinfo = up_getvideoinfo, + fbinfo->vtable.getplaneinfo = up_getplaneinfo, +#ifdef CONFIG_FB_CMAP + fbinfo->vtable.getcmap = up_getcmap, + fbinfo->vtable.putcmap = up_putcmap, +#endif +#ifdef CONFIG_FB_HWCURSOR + fbinfo->vtable.getcursor = up_getcursor, + fbinfo->vtable.setcursor = up_setcursor, +#endif + fbinfo->display = display; + fbinfo->initialized = true; + } + + return &fbinfo->vtable; + } + else + { + return NULL; + } +} + +/**************************************************************************** + * Name: up_fbuninitialize + * + * Description: + * Uninitialize the framebuffer support for the specified display. + * + * Input Parameters: + * display - In the case of hardware with multiple displays, this + * specifies the display. Normally this is zero. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_fbuninitialize(int display) +{ +#if 0 /* Do nothing */ + FAR struct vnc_session_s *session = vnc_find_session(display); + FAR struct vnc_fbinfo_s *fbinfo; + + DEBUGASSERT(session != NULL); + fbinfo = &g_fbinfo[display]; +#warning Missing logic + UNUSED(session); + UNUSED(fbinfo); +#endif +} + +/**************************************************************************** + * Name: nx_notify_rectangle + * + * Description: + * When CONFIG_NX_UPDATE=y, then the graphics system will callout to + * inform some external module that the display has been updated. This + * would be useful in a couple for cases. + * + * - When a serial LCD is used, but a framebuffer is used to access the + * LCD. In this case, the update callout can be used to refresh the + * affected region of the display. + * + * - When VNC is enabled. This is case, this callout is necessary to + * update the remote frame buffer to match the local framebuffer. + * + * When this feature is enabled, some external logic must provide this + * interface. This is the function that will handle the notification. It + * receives the rectangular region that was updated on the provided plane. + * + ****************************************************************************/ + +#ifdef CONFIG_NX_UPDATE +void nx_notify_rectangle(FAR NX_PLANEINFOTYPE *pinfo, + FAR const struct nxgl_rect_s *rect) +{ + FAR struct vnc_session_s *session; + int ret; + + DEBUGASSERT(pinfo != NULL && rect != NULL); + + /* Recover the session informatin from the display number in the planeinfo + * structure. + */ + + DEBUGASSERT(pinfo->display >= 0 && pinfo->display < RFB_MAX_DISPLAYS); + session = vnc_find_session(pinfo->display); + + /* Verify that the session is still valid */ + + if (session != NULL && session->state == VNCSERVER_RUNNING) + { + /* Queue the rectangular update */ + + ret = vnc_update_rectangle(session, rect); + if (ret < 0) + { + gdbg("ERROR: vnc_update_rectangle failed: %d\n", ret); + } + } +} +#endif diff --git a/graphics/vnc/server/vnc_keymap.c b/graphics/vnc/server/vnc_keymap.c new file mode 100644 index 00000000000..57690183f46 --- /dev/null +++ b/graphics/vnc/server/vnc_keymap.c @@ -0,0 +1,632 @@ +/**************************************************************************** + * graphics/vnc/vnc_keymap.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#define XK_MISCELLANY 1 /* Select X11 character set */ +#define XK_LATIN1 1 +#define XK_XKB_KEYS 1 + +#include +#include + +#include "vnc_server.h" + +#ifdef CONFIG_NX_KBD + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define FIRST_PRTCHAR ASCII_SPACE +#define LAST_PRTCHAR ASCII_TILDE +#define NPRTCHARS (ASCII_TILDE + ASCII_SPACE - 1) + +#define ISPRINTABLE(c) ((c) >= FIRST_PRTCHAR && (c) <= LAST_PRTCHAR) +#define ISLOWERCASE(c) ((c) >= ASCII_a && (c) <= ASCII_z) +#define ISUPPERCASE(c) ((c) >= ASCII_A && (c) <= ASCII_Z) +#define ISALPHABETIC(c) (ISLOWERCASE(c) || ISUPPERCASE(c)) + +/**************************************************************************** + * Private types + ****************************************************************************/ + +enum vnc_modifier_e +{ + MOD_SHIFT = 0, /* Left or right shift key */ + MOD_CONTROL, /* Left or right control key */ + MOD_ALT, /* Alt key */ + MOD_CAPSLOCK, /* Caps lock */ + MOD_SHIFTLOCK, /* Shift lock */ +#ifdef CONFIG_VNCSERVER_KBDENCODE + MOD_SCROLLLOCK, /* Scroll lock */ + MOD_NUMLOCK, /* Num lock */ +#endif + NMODIFIERS +}; + +struct vnc_keymap_s +{ + uint16_t nxcode; + uint16_t x11code; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Special key modifiers */ + +static const struct vnc_keymap_s g_modifiers[] = +{ + {MOD_SHIFT, XK_Shift_L}, + {MOD_SHIFT, XK_Shift_R}, + {MOD_CONTROL, XK_Control_L}, + {MOD_CONTROL, XK_Control_R}, + {MOD_ALT, XK_Alt_L}, + {MOD_ALT, XK_Alt_R}, + {MOD_CAPSLOCK, XK_Caps_Lock}, + {MOD_SHIFTLOCK, XK_Shift_Lock}, +#ifdef CONFIG_VNCSERVER_KBDENCODE + {MOD_SCROLLLOCK, XK_Scroll_Lock}, + {MOD_NUMLOCK, XK_Num_Lock}, +#endif +}; + +#define G_MODIFIERS_NELEM (sizeof(g_modifiers) / sizeof(struct vnc_keymap_s)) + +/* Map special mappings for X11 codes to ASCII characters */ + +static const struct vnc_keymap_s g_asciimap[] = +{ + /* Control characters */ + +#ifdef CONFIG_VNCSERVER_KBDENCODE + {ASCII_BS, XK_BackSpace}, +#endif + {ASCII_TAB, XK_Tab}, + {ASCII_LF, XK_Linefeed}, + {ASCII_CR, XK_Return}, + {ASCII_ESC, XK_Escape}, +#ifdef CONFIG_VNCSERVER_KBDENCODE + {ASCII_DEL, XK_Delete}, +#endif + + /* Alternative encodings */ + + {'`', XK_dead_grave}, + {'´', XK_dead_acute}, + {ASCII_TILDE, XK_dead_tilde}, + {ASCII_CARET, XK_dead_circumflex}, + + /* Keypad aliases */ + + {ASCII_0, XK_KP_0}, + {ASCII_1, XK_KP_1}, + {ASCII_2, XK_KP_2}, + {ASCII_3, XK_KP_3}, + {ASCII_4, XK_KP_4}, + {ASCII_5, XK_KP_5}, + {ASCII_6, XK_KP_6}, + {ASCII_7, XK_KP_7}, + {ASCII_8, XK_KP_8}, + {ASCII_9, XK_KP_9}, + + {ASCII_ASTERISK, XK_KP_Multiply}, + {ASCII_PLUS, XK_KP_Add}, + {ASCII_COMMA, XK_KP_Separator}, + {ASCII_HYPHEN, XK_KP_Subtract}, + {ASCII_PERIOD, XK_KP_Decimal}, + {ASCII_DIVIDE, XK_KP_Divide}, + + {ASCII_SPACE, XK_KP_Space}, + {ASCII_TAB, XK_KP_Tab}, + {ASCII_CR, XK_KP_Enter} +#ifdef CONFIG_VNCSERVER_KBDENCODE + , {ASCII_DEL, XK_KP_Delete} +#endif +}; + +#define G_ASCIIMAP_NELEM (sizeof(g_asciimap) / sizeof(struct vnc_keymap_s)) + +#ifdef CONFIG_VNCSERVER_KBDENCODE +static const struct vnc_keymap_s g_cursor[] = +{ + {KEYCODE_BACKDEL, XK_BackSpace}, + {KEYCODE_FWDDEL, XK_Delete}, + {KEYCODE_FWDDEL, XK_KP_Delete}, + {KEYCODE_HOME, XK_Home}, + {KEYCODE_HOME, XK_KP_Home}, + {KEYCODE_END, XK_End}, + {KEYCODE_END, XK_KP_End}, + {KEYCODE_LEFT, XK_Left}, + {KEYCODE_LEFT, XK_KP_Left}, + {KEYCODE_RIGHT, XK_Right}, + {KEYCODE_RIGHT, XK_KP_Right}, + {KEYCODE_UP, XK_Up}, + {KEYCODE_UP, XK_KP_Up}, + {KEYCODE_DOWN, XK_Down}, + {KEYCODE_DOWN, XK_KP_Down}, + {KEYCODE_PAGEUP, XK_Page_Up}, + {KEYCODE_PAGEUP, XK_KP_Prior}, + {KEYCODE_PAGEUP, XK_KP_Page_Up}, + {KEYCODE_PAGEDOWN, XK_Page_Down}, + {KEYCODE_PAGEDOWN, XK_KP_Next}, + {KEYCODE_PAGEDOWN, XK_KP_Page_Down}, + {KEYCODE_INSERT, XK_Insert}, + {KEYCODE_INSERT, XK_KP_Insert}, + + {KEYCODE_SELECT, XK_Select}, + {KEYCODE_EXECUTE, XK_Execute}, + {KEYCODE_HELP, XK_Help}, + {KEYCODE_MENU, XK_Alt_L}, + {KEYCODE_MENU, XK_Alt_R}, + {KEYCODE_PAUSE, XK_Pause}, + {KEYCODE_PRTSCRN, XK_Print}, + {KEYCODE_CLEAR, XK_Clear}, + {MOD_SCROLLLOCK, XK_Scroll_Lock}, + {MOD_NUMLOCK, XK_Num_Lock}, + + {KEYCODE_F1, XK_KP_F1}, + {KEYCODE_F1, XK_F1}, + {KEYCODE_F2, XK_KP_F2}, + {KEYCODE_F2, XK_F2}, + {KEYCODE_F3, XK_KP_F3}, + {KEYCODE_F3, XK_F3}, + {KEYCODE_F4, XK_KP_F4}, + {KEYCODE_F4, XK_F4}, + {KEYCODE_F5, XK_F5}, + {KEYCODE_F6, XK_F6}, + {KEYCODE_F7, XK_F7}, + {KEYCODE_F8, XK_F8}, + {KEYCODE_F9, XK_F9}, + {KEYCODE_F10, XK_F10}, + {KEYCODE_F11, XK_F11}, + {KEYCODE_F12, XK_F12}, + {KEYCODE_F13, XK_F13}, + {KEYCODE_F14, XK_F14}, + {KEYCODE_F15, XK_F15}, + {KEYCODE_F16, XK_F16}, + {KEYCODE_F17, XK_F17}, + {KEYCODE_F18, XK_F18}, + {KEYCODE_F19, XK_F19}, + {KEYCODE_F20, XK_F20}, + {KEYCODE_F21, XK_F21}, + {KEYCODE_F22, XK_F22}, + {KEYCODE_F23, XK_F23}, + {KEYCODE_F24, XK_F24}, +}; +#endif + +/* Changes the case of a character. Based on US keyboard layout */ + +static const uint8_t g_caseswap[NPRTCHARS] = +{ + ASCII_SPACE, ASCII_1, ASCII_RSQUOTE, ASCII_3, /* ! " # */ + ASCII_4, ASCII_5, ASCII_7, ASCII_QUOTE, /* $ % & ' */ + ASCII_9, ASCII_0, ASCII_8, ASCII_EQUAL, /* ( ) * + */ + ASCII_LT, ASCII_UNDERSCORE, ASCII_GT, ASCII_QUESTION, /* , - . / */ + ASCII_RPAREN, ASCII_EXCLAM, ASCII_AT, ASCII_NUMBER, /* 0 1 2 3 */ + ASCII_DOLLAR, ASCII_PERCENT, ASCII_CIRCUMFLEX, ASCII_AMPERSAND, /* 4 5 6 7 */ + ASCII_ASTERISK, ASCII_LPAREN, ASCII_SEMICOLON, ASCII_COLON, /* 8 9 : ; */ + ASCII_COMMA, ASCII_PLUS, ASCII_PERIOD, ASCII_SLASH, /* < = > ? */ + ASCII_2, ASCII_a, ASCII_b, ASCII_c, /* @ A B C */ + ASCII_d, ASCII_e, ASCII_f, ASCII_g, /* D E F G */ + ASCII_h, ASCII_i, ASCII_j, ASCII_k, /* H I J K */ + ASCII_l, ASCII_m, ASCII_n, ASCII_o, /* L M N O */ + ASCII_p, ASCII_q, ASCII_r, ASCII_s, /* P Q R S */ + ASCII_t, ASCII_u, ASCII_v, ASCII_v, /* T U V W */ + ASCII_x, ASCII_y, ASCII_z, ASCII_LBRACE, /* X Y Z [ */ + ASCII_VERTBAR, ASCII_RBRACE, ASCII_6, ASCII_HYPHEN, /* \ ] ^ _ */ + ASCII_TILDE, ASCII_A, ASCII_B, ASCII_C, /* ' a b c */ + ASCII_D, ASCII_E, ASCII_F, ASCII_G, /* c e f g */ + ASCII_H, ASCII_I, ASCII_J, ASCII_K, /* h i j k */ + ASCII_L, ASCII_M, ASCII_N, ASCII_O, /* l m n o */ + ASCII_P, ASCII_Q, ASCII_R, ASCII_S, /* p q r s */ + ASCII_T, ASCII_U, ASCII_V, ASCII_W, /* t u v w */ + ASCII_X, ASCII_Y, ASCII_Z, ASCII_LBRACKET, /* x y z { */ + ASCII_BACKSLASH, ASCII_RBRACKET, ASCII_RSQUOTE, /* | } ~ */ +}; + +/* State of each modifier */ + +static bool g_modstate[NMODIFIERS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_kbd_encode + * + * Description: + * Encode one escape sequence command into the proivded buffer. + * + * Input Parameters: + * buffer - The location to write the sequence + * keycode - The command to be added to the output stream. + * terminator - Escape sequence terminating character. + * + * Returned Value: + * Number of bytes written + * + ****************************************************************************/ + +#ifdef CONFIG_VNCSERVER_KBDENCODE +static inline int vnc_kbd_encode(FAR uint8_t *buffer, uint8_t keycode, + uint8_t terminator) +{ + *buffer++ = ASCII_ESC; + *buffer++ = ASCII_LBRACKET; + *buffer++ = keycode; + *buffer = terminator; + return 4; +} +#endif + +/**************************************************************************** + * Name: vnc_kbd_press + * + * Description: + * Indicates a normal key press event. Put one byte of normal keyboard + * data into the user provided buffer. + * + * Input Parameters: + * buffer - The location to write the sequence + * ch - The character to be added to the output stream. + * + * Returned Value: + * Number of bytes written + * + ****************************************************************************/ + +#ifdef CONFIG_VNCSERVER_KBDENCODE +static inline void vnc_kbd_press(FAR uint8_t *buffer, uint8_t ch) +{ + *buffer = ch; + return 1; +} +#endif + +/**************************************************************************** + * Name: vnc_kbd_release + * + * Description: + * Encode the release of a normal key. + * + * Input Parameters: + * buffer - The location to write the sequence + * ch - The character associated with the key that was releared. + * + * Returned Value: + * Number of bytes written + * + ****************************************************************************/ + +#ifdef CONFIG_VNCSERVER_KBDENCODE +static inline void vnc_kbd_release(FAR uint8_t *buffer, uint8_t ch) +{ + return vnc_kbd_encode(buffer, ch, ('a' + KBD_RELEASE)); +} +#endif + +/**************************************************************************** + * Name: vnc_kbd_specpress + * + * Description: + * Denotes a special key press event. Put one special keyboard command + * into the user provided buffer. + * + * Input Parameters: + * buffer - The location to write the sequence + * keycode - The command to be added to the output stream. + * + * Returned Value: + * Number of bytes written + * + ****************************************************************************/ + +#ifdef CONFIG_VNCSERVER_KBDENCODE +static inline void vnc_kbd_specpress(FAR uint8_t *buffer, uint8_t keycode) +{ + return vnc_kbd_encode(buffer, keycode, stream, ('a' + KBD_SPECPRESS)); +} +#endif + +/**************************************************************************** + * Name: vnc_kbd_specrel + * + * Description: + * Denotes a special key release event. Put one special keyboard + * command into the user provided buffer. + * + * Input Parameters: + * buffer - The location to write the sequence + * keycode - The command to be added to the output stream. + * + * Returned Value: + * Number of bytes written + * + ****************************************************************************/ + +#ifdef CONFIG_VNCSERVER_KBDENCODE +static inline void vnc_kbd_specrel(FAR uint8_t *buffer, uint8_t keycode) +{ + return vnc_kbd_encode(buffer, keycode, stream, ('a' + KBD_SPECREL)); +} +#endif + +/**************************************************************************** + * Name: vnc_kbd_lookup + * + * Description: + * Attempt to map the X11 keycode by searching in a lookup table. + * + ****************************************************************************/ + +static int vnc_kbd_lookup(FAR const struct vnc_keymap_s *table, + unsigned int nelem, uint16_t keysym) +{ + int i; + + /* First just try to map the virtual keycode using our lookup-table */ + + for (i = 0; i < nelem; i++) + { + if (table[i].x11code == keysym) + { + /* We have a match */ + + return (int)table[i].nxcode; + } + } + + /* No match */ + + return -EINVAL; +} + +/**************************************************************************** + * Name: vnc_kbd_ascii + * + * Description: + * Attempt to map the X11 keycode into the corresponding ASCII code. + * + ****************************************************************************/ + +static int vnc_kbd_ascii(uint16_t keysym) +{ + /* ISO/IEC 8859-1 Latin1 matches C ASCII in this range: */ + +#ifdef CONFIG_VNCSERVER_KBDENCODE + if (keysym >= ASCII_SPACE && keysym < ASCII_DEL) +#else + if (keysym >= ASCII_SPACE && keysym <= ASCII_DEL) +#endif + { + return (int)keysym; + } + + /* Perform a lookup to handler some special cases */ + + return vnc_kbd_lookup(g_asciimap, G_ASCIIMAP_NELEM, keysym); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_key_map + * + * Description: + * Map the receive X11 keysym into something understood by NuttX and route + * that through NX to the appropriate window. + * + * Input Parameters: + * session - An instance of the session structure allocated by + * vnc_create_session(). + * keysym - The X11 keysym value (see include/nuttx/inputx11_keysymdef) + * keydown - True: Key pressed; False: Key released + * + * Returned Value: + * None + * + ****************************************************************************/ + +void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym, + bool keydown) +{ +#ifdef CONFIG_VNCSERVER_KBDENCODE + uint8_t buffer[4] + int nch; +#endif + int16_t keych; + int ret; + + /* Check for modifier keys */ + + keych = vnc_kbd_lookup(g_modifiers, G_MODIFIERS_NELEM, keysym); + if (keych >= 0) + { + g_modstate[keych] = keydown; + return; + } + +#ifndef CONFIG_VNCSERVER_KBDENCODE + /* If we are not encoding key presses, then we have to ignore key release + * events. + */ + + if (!keydown) + { + return; + } +#endif + + /* Try to convert the keycode to an ASCII value */ + + keych = vnc_kbd_ascii((char)(keysym & 255)); + if (keych >= 0) + { + /* It is a simple ASCII-mappable LATIN1 character. Now we need + * to apply any modifiers. + */ + + if (g_modstate[MOD_CONTROL]) + { + /* Make into a control character */ + + keych &= 0x1f; + } + + /* Other modifiers apply only to printable characters */ + + else if (ISPRINTABLE(keych)) + { + /* If Shift Lock is selected, then the case of all printable + * characters should be reversed (unless the Shift key is also + * pressed) + */ + + if (g_modstate[MOD_SHIFTLOCK]) + { + if (g_modstate[MOD_SHIFT]) + { + /* Swap case */ + + keych = g_caseswap[keych]; + } + } + + /* If Caps Lock is selected, then the case of alphabetic + * characters should be reversed (unless the Shift key is also + * pressed) + */ + + else if (g_modstate[MOD_CAPSLOCK] && ISALPHABETIC(keych)) + { + if (g_modstate[MOD_SHIFT]) + { + /* Swap case */ + + keych = g_caseswap[keych]; + } + } + + /* If (1) only the Shift Key is pressed or (2) the Shift key is + * pressed with Caps Lock, but the character is not alphabetic, + * then the case of all printable characters should be reversed. + */ + + else if (g_modstate[MOD_SHIFT]) + { + keych = g_caseswap[keych]; + } + } + +#ifdef CONFIG_VNCSERVER_KBDENCODE + /* Encode the normal character */ + + if (keydown) + { + nch = vnc_kbd_press(buffer, keych); + } + else + { + nch = vnc_kbd_release(buffer, keych); + } + + /* 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); + } +#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); + } +#endif + } + + /* Not mappable to an ASCII LATIN1 character */ + +#ifdef CONFIG_VNCSERVER_KBDENCODE + else + { + /* Lookup cursor movement/screen control keysyms */ + + keych = vnc_kbd_lookup(g_modifiers, G_MODIFIERS_NELEM, keysym); + if (keych >= 0) + { + /* Encode the speical character */ + + if (keydown) + { + nch = vnc_kbd_specpress(buffer, keych); + } + else + { + nch = vnc_kbd_specrel(buffer, keych); + } + + /* 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) + } + } + } +#endif +} + +#endif /* CONFIG_NX_KBD */ \ No newline at end of file diff --git a/graphics/vnc/server/vnc_negotiate.c b/graphics/vnc/server/vnc_negotiate.c new file mode 100644 index 00000000000..7c229814cbc --- /dev/null +++ b/graphics/vnc/server/vnc_negotiate.c @@ -0,0 +1,337 @@ +/**************************************************************************** + * graphics/vnc/vnc_negotiate.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "vnc_server.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if defined(CONFIG_VNCSERVER_PROTO3p3) +static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p3; +#elif defined(CONFIG_VNCSERVER_PROTO3p8) +static const char g_vncproto[] = RFB_PROTOCOL_VERSION_3p8; +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_negotiate + * + * Description: + * Perform the VNC initialization sequence after the client has sucessfully + * connected to the server. Negotiate security, framebuffer and color + * properties. + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * Returns zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_VNCSERVER_PROTO3p3 +int vnc_negotiate(FAR struct vnc_session_s *session) +{ + FAR struct rfb_sectype_s *sectype; + FAR struct rfb_serverinit_s *serverinit; + FAR struct rfb_pixelfmt_s *pixelfmt; + FAR struct rfb_setpixelformat_s *setformat; + ssize_t nsent; + ssize_t nrecvd; + size_t len; + int errcode; + + /* Inform the client of the VNC protocol version */ + + gvdbg("Send protocol version: %s\n", g_vncproto); + + len = strlen(g_vncproto); + nsent = psock_send(&session->connect, g_vncproto, len, 0); + if (nsent < 0) + { + errcode = get_errno(); + gdbg("ERROR: Send ProtocolVersion failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nsent == len); + + /* Receive the echo of the protocol string */ + + gvdbg("Receive echo from VNC client\n"); + + nrecvd = psock_recv(&session->connect, session->inbuf, len, 0); + if (nrecvd < 0) + { + errcode = get_errno(); + gdbg("ERROR: Receive protocol confirmation failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nrecvd == len); + + /* Tell the client that we won't use any stinkin' security. + * + * "Version 3.3 The server decides the security type and sends a single + * word:" + */ + + gvdbg("Send security type (None)\n"); + + sectype = (FAR struct rfb_sectype_s *)session->outbuf; + rfb_putbe32(sectype->type, RFB_SECTYPE_NONE); + + nsent = psock_send(&session->connect, sectype, + sizeof(struct rfb_sectype_s), 0); + if (nsent < 0) + { + errcode = get_errno(); + gdbg("ERROR: Send Security failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nsent == sizeof(struct rfb_sectype_s)); + + /* Receive the ClientInit message + * + * "Once the client and server are sure that they’re happy to talk to one + * another using the agreed security type, the protocol passes to the + * initialisation phase. The client sends a ClientInit message followed + * by the server sending a ServerInit message." + * + * In this implementation, the sharing flag is ignored. + */ + + gvdbg("Receive ClientInit\n"); + + nrecvd = psock_recv(&session->connect, session->inbuf, + sizeof(struct rfb_clientinit_s), 0); + if (nrecvd < 0) + { + errcode = get_errno(); + gdbg("ERROR: Receive ClientInit failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nrecvd == sizeof(struct rfb_clientinit_s)); + + /* Send the ServerInit message + * + * "After receiving the ClientInit message, the server sends a ServerInit + * message. This tells the client the width and height of the server’s + * framebuffer, its pixel format and the name associated with the desktop: + */ + + gvdbg("Receive ServerInit\n"); + + serverinit = (FAR struct rfb_serverinit_s *)session->outbuf; + + rfb_putbe16(serverinit->width, CONFIG_VNCSERVER_SCREENWIDTH); + rfb_putbe16(serverinit->height, CONFIG_VNCSERVER_SCREENHEIGHT); + rfb_putbe32(serverinit->namelen, 0); + + pixelfmt = &serverinit->format; + pixelfmt->bpp = RFB_BITSPERPIXEL; + pixelfmt->depth = RFB_PIXELDEPTH; + pixelfmt->bigendian = 0; + pixelfmt->truecolor = RFB_TRUECOLOR; + + rfb_putbe16(pixelfmt->rmax, RFB_RMAX); + rfb_putbe16(pixelfmt->gmax, RFB_GMAX); + rfb_putbe16(pixelfmt->bmax, RFB_BMAX); + + pixelfmt->rshift = RFB_RSHIFT; + pixelfmt->gshift = RFB_GSHIFT; + pixelfmt->bshift = RFB_BSHIFT; + + nsent = psock_send(&session->connect, serverinit, + SIZEOF_RFB_SERVERINIT_S(0), 0); + if (nsent < 0) + { + errcode = get_errno(); + gdbg("ERROR: Send ServerInit failed: %d\n", errcode); + return -errcode; + } + + DEBUGASSERT(nsent == SIZEOF_RFB_SERVERINIT_S(0)); + + /* We now expect to receive the SetPixelFormat message from the client. + * This may override some of our framebuffer settings. + */ + + gvdbg("Receive SetPixelFormat\n"); + + setformat = (FAR struct rfb_setpixelformat_s *)session->inbuf; + + nrecvd = psock_recv(&session->connect, setformat, + sizeof(struct rfb_setpixelformat_s), 0); + if (nrecvd < 0) + { + errcode = get_errno(); + gdbg("ERROR: Receive SetFormat failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + else if (nrecvd != sizeof(struct rfb_setpixelformat_s)) + { + /* Must not be a SetPixelFormat message? */ + + gdbg("ERROR: SetFormat wrong size: %d\n", (int)nrecvd); + return -EPROTO; + } + else if (setformat->msgtype != RFB_SETPIXELFMT_MSG) + { + gdbg("ERROR: Not a SetFormat message: %d\n", (int)setformat->msgtype); + return -EPROTO; + } + + /* Check if the client request format is one that we can handle. */ + + pixelfmt = &setformat->format; + + if (pixelfmt->truecolor == 0) + { + /* At present, we support only TrueColor formats */ + + gdbg("ERROR: No support for palette colors\n"); + return -ENOSYS; + } + + if (pixelfmt->bpp == 16 && pixelfmt->depth == 15) + { + session->colorfmt = FB_FMT_RGB16_555; + session->bpp = 16; + } + else if (pixelfmt->bpp == 16 && pixelfmt->depth == 16) + { + session->colorfmt = FB_FMT_RGB16_565; + session->bpp = 16; + } + else if (pixelfmt->bpp == 32 && pixelfmt->depth == 24) + { + session->colorfmt = FB_FMT_RGB32; + session->bpp = 32; + } + else if (pixelfmt->bpp == 32 && pixelfmt->depth == 32) + { + session->colorfmt = FB_FMT_RGB32; + session->bpp = 32; + } + else + { + /* We do not support any other conversions */ + + gdbg("ERROR: No support for this BPP=%d and depth=%d\n", + pixelfmt->bpp, pixelfmt->depth); + return -ENOSYS; + } + + /* Receive supported encoding types from client, but ignore them. + * we will do only raw format. + */ + + gvdbg("Receive encoding types\n"); + + (void)psock_recv(&session->connect, session->inbuf, + CONFIG_VNCSERVER_INBUFFER_SIZE, 0); + + session->state = VNCSERVER_CONFIGURED; + return OK; +} +#endif + +#ifdef CONFIG_VNCSERVER_PROTO3p8 +int vnc_negotiate(FAR struct vnc_session_s *session) +{ + ssize_t nsent; + ssize_t nrecvd; + size_t len; + + /* Inform the client of the VNC protocol version */ + + len = strlen(g_vncproto); + nsent = psock_send(&session->connect, g_vncproto, len, 0); + if (nsent < 0) + { + errcode = get_errno(); + gdbg("ERROR: Send ProtocolVersion failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nsent == len); + + /* Receive the echo of the protocol string */ + + nrecvd = psock_recv(&session->connect, session->inbuf, len, 0); + if (nrecvd <= 0) + { + errcode = get_errno(); + gdbg("ERROR: Receive protocol confirmation failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nrecvd == len); + + /* Offer the client a choice of security -- where None is the only option. */ +#warning Missing logic + + return OK; +} +#endif diff --git a/graphics/vnc/server/vnc_receiver.c b/graphics/vnc/server/vnc_receiver.c new file mode 100644 index 00000000000..a74fc1a68d6 --- /dev/null +++ b/graphics/vnc/server/vnc_receiver.c @@ -0,0 +1,383 @@ +/**************************************************************************** + * graphics/vnc/vnc_receiver.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "vnc_server.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_read_remainder + * + * Description: + * After receiving the first byte of a client-to-server message, this + * reads in the remainder of the message. + * + * Input Parameters: + * session - An instance of the session structure. + * msglen - The full length of the message + * + * Returned Value: + * At present, always returns OK + * + ****************************************************************************/ + +int vnc_read_remainder(FAR struct vnc_session_s *session, size_t msglen, + size_t offset) +{ + ssize_t nrecvd; + size_t ntotal; + int errcode; + + /* Loop until the rest of the message is recieved. */ + + for (ntotal = 0; ntotal < msglen; offset += nrecvd, ntotal += nrecvd) + { + /* Receive more of the message */ + + nrecvd = psock_recv(&session->connect, &session->inbuf[offset], + msglen - ntotal, 0); + if (nrecvd < 0) + { + errcode = get_errno(); + gdbg("ERROR: Receive message failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_receiver + * + * Description: + * This function handles all Client-to-Server messages. + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * At present, always returns OK + * + ****************************************************************************/ + +int vnc_receiver(FAR struct vnc_session_s *session) +{ + ssize_t nrecvd; + int errcode; + int ret; + + DEBUGASSERT(session); + gvdbg("Receiver running for Display %d\n", session->display); + + /* Loop until the client disconnects or an unhandled error occurs */ + + for (; ; ) + { + /* Set up to read one byte which should be the message type of the + * next Client-to-Server message. We will block here until the message + * is received. + */ + + nrecvd = psock_recv(&session->connect, session->inbuf, 1, 0); + if (nrecvd < 0) + { + errcode = get_errno(); + gdbg("ERROR: Receive byte failed: %d\n", errcode); + DEBUGASSERT(errcode > 0); + return -errcode; + } + + DEBUGASSERT(nrecvd == 1); + + /* The single byte received should be the message type. Handle the + * message according to this message type. + */ + + switch (session->inbuf[0]) + { + case RFB_SETPIXELFMT_MSG: /* SetPixelFormat */ + { + gvdbg("Received SetPixelFormat\n"); + + /* Read the rest of the SetPixelFormat message */ + + ret = vnc_read_remainder(session, + sizeof(struct rfb_setpixelformat_s) - 1, + 1); + if (ret < 0) + { + gdbg("ERROR: Failed to read SetPixelFormat message: %d\n", + ret); + } + else + { + /* REVISIT: SetPixelFormat is currently ignored */ + } + } + break; + + case RFB_SETENCODINGS_MSG: /* SetEncodings */ + { + FAR struct rfb_setencodings_s *encodings; + uint32_t nencodings; + + gvdbg("Received SetEncodings\n"); + + /* Read the SetEncodings message without the following + * encodings. + */ + + ret = vnc_read_remainder(session, + SIZEOF_RFB_SERVERINIT_S(0) - 1, + 1); + if (ret < 0) + { + gdbg("ERROR: Failed to read SetEncodings message: %d\n", + ret); + } + else + { + /* Read the following encodings */ + + encodings = (FAR struct rfb_setencodings_s *)session->inbuf; + nencodings = rfb_getbe32(encodings->nencodings); + + ret = vnc_read_remainder(session, + nencodings * sizeof(uint32_t), + SIZEOF_RFB_SERVERINIT_S(0)); + if (ret < 0) + { + gdbg("ERROR: Failed to read encodings: %d\n", + ret); + } + else + { + /* REVISIT: SetEncodings is currently ignored */ + } + } + } + break; + + case RFB_FBUPDATEREQ_MSG: /* FramebufferUpdateRequest */ + { + FAR struct rfb_fbupdatereq_s *update; + struct nxgl_rect_s rect; + + gvdbg("Received FramebufferUpdateRequest\n"); + + /* Read the rest of the SetPixelFormat message */ + + ret = vnc_read_remainder(session, + sizeof(struct rfb_fbupdatereq_s) - 1, + 1); + if (ret < 0) + { + gdbg("ERROR: Failed to read FramebufferUpdateRequest message: %d\n", + ret); + } + else + { + /* Enqueue the update */ + + update = (FAR struct rfb_fbupdatereq_s *)session->inbuf; + + rect.pt1.x = rfb_getbe16(update->xpos); + rect.pt1.y = rfb_getbe16(update->ypos); + rect.pt2.x = rect.pt1.x + rfb_getbe16(update->width); + rect.pt2.y = rect.pt1.y + rfb_getbe16(update->height); + + ret = vnc_update_rectangle(session, &rect); + if (ret < 0) + { + gdbg("ERROR: Failed to queue update: %d\n", ret); + } + } + } + break; + + case RFB_KEYEVENT_MSG: /* KeyEvent */ + { + FAR struct rfb_keyevent_s *keyevent; + + gvdbg("Received KeyEvent\n"); + + /* Read the rest of the KeyEvent message */ + + ret = vnc_read_remainder(session, + sizeof(struct rfb_keyevent_s) - 1, + 1); + if (ret < 0) + { + gdbg("ERROR: Failed to read KeyEvent message: %d\n", + ret); + } + else + { + /* Inject the key press/release event into NX */ + + keyevent = (FAR struct rfb_keyevent_s *)session->inbuf; + vnc_key_map(session, rfb_getbe16(keyevent->key), + (bool)keyevent->down); + } + } + break; + + case RFB_POINTEREVENT_MSG: /* PointerEvent */ + { +#ifdef CONFIG_NX_XYINPUT + FAR struct rfb_pointerevent_s *event; + uint8_t buttons; +#endif + gvdbg("Received PointerEvent\n"); + + /* Read the rest of the PointerEvent message */ + + ret = vnc_read_remainder(session, + sizeof(struct rfb_pointerevent_s) - 1, + 1); + if (ret < 0) + { + gdbg("ERROR: Failed to read PointerEvent message: %d\n", + ret); + } +#ifdef CONFIG_NX_XYINPUT + else + { + event = (FAR struct rfb_pointerevent_s *)session->inbuf; + + /* Map buttons bitmap. Bits 0-7 are buttons 1-8, 0=up, + * 1=down. By convention Bit 0 = left button, Bit 1 = + * middle button, and Bit 2 = right button. + */ + + buttons = 0; + if ((event->buttons & (1 << 0)) != 0) + { + buttons |= NX_MOUSE_LEFTBUTTON; + } + + if ((event->buttons & (1 << 1)) != 0) + { + buttons |= NX_MOUSE_CENTERBUTTON; + } + + if ((event->buttons & (1 << 2)) != 0) + { + buttons |= NX_MOUSE_RIGHTBUTTON; + } + + ret = nx_mousein(session->handle, + (nxgl_coord_t)rfb_getbe16(event->xpos), + (nxgl_coord_t)rfb_getbe16(event->ypos), + buttons); + if (ret < 0) + { + gdbg("ERROR: nx_mousein failed: %d\n", ret); + } + } +#endif + } + break; + + case RFB_CLIENTCUTTEXT_MSG: /* ClientCutText */ + { + FAR struct rfb_clientcuttext_s *cuttext; + uint32_t length; + + gvdbg("Received ClientCutText\n"); + + /* Read the ClientCutText message without the following + * text. + */ + + ret = vnc_read_remainder(session, + SIZEOF_RFB_CLIENTCUTTEXT_S(0) - 1, + 1); + if (ret < 0) + { + gdbg("ERROR: Failed to read ClientCutText message: %d\n", + ret); + } + else + { + /* Read the following text */ + + cuttext = (FAR struct rfb_clientcuttext_s *)session->inbuf; + length = rfb_getbe32(cuttext->length); + + ret = vnc_read_remainder(session, length, + SIZEOF_RFB_CLIENTCUTTEXT_S(0)); + if (ret < 0) + { + gdbg("ERROR: Failed to read text: %d\n", + ret); + } + else + { + /* REVISIT: ClientCutText is currently ignored */ + } + } + } + break; + + default: + gdbg("ERROR: Unsynchronized, msgtype=%d\n", session->inbuf[0]); + return -EPROTO; + } + } + + return -ENOSYS; +} diff --git a/graphics/vnc/server/vnc_server.c b/graphics/vnc/server/vnc_server.c new file mode 100644 index 00000000000..eba4afb8189 --- /dev/null +++ b/graphics/vnc/server/vnc_server.c @@ -0,0 +1,393 @@ +/**************************************************************************** + * graphics/vnc/vnc_server.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "nuttx/config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "vnc_server.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Given a display number as an index, the following array can be used to + * look-up the session structure for that display. + */ + +FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_reset_session + * + * Description: + * Conclude the current VNC session. This function re-initializes the + * session structure; it does not free either the session structure nor + * the framebuffer so that they may be re-used. + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vnc_reset_session(FAR struct vnc_session_s *session, + FAR uint8_t *fb, int display) +{ + FAR struct vnc_fbupdate_s *curr; + FAR struct vnc_fbupdate_s *next; + int i; + + /* Close any open sockets */ + + if (session->state >= VNCSERVER_CONNECTED) + { + psock_close(&session->connect); + psock_close(&session->listen); + } + + /* [Re-]initialize the session. */ + + memset(&session->connect, 0, sizeof(struct socket)); + session->connect.s_crefs = 1; + memset(&session->listen, 0, sizeof(struct socket)); + session->listen.s_crefs = 1; + + /* Put all of the pre-allocated update structures into the freelist */ + + sq_init(&session->updqueue); + + session->updfree.head = + (FAR sq_entry_t *)&session->updpool[0]; + session->updfree.tail = + (FAR sq_entry_t *)&session->updpool[CONFIG_VNCSERVER_NUPDATES-1]; + + next = &session->updpool[0]; + for (i = 1; i < CONFIG_VNCSERVER_NUPDATES-1; i++) + { + curr = next; + next = &session->updpool[i]; + curr->flink = next; + } + + next->flink = NULL; + + /* Set the INITIALIZED state */ + + sem_reset(&session->freesem, CONFIG_VNCSERVER_NUPDATES); + sem_reset(&session->queuesem, 0); + session->fb = fb; + session->display = display; + session->state = VNCSERVER_INITIALIZED; +} + +/**************************************************************************** + * Name: vnc_connect + * + * Description: + * Wait for a connection from the VNC client + * + * Input Parameters: + * session - An instance of the session structure. + * port - The listen port to use + * + * Returned Value: + * Returns zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int vnc_connect(FAR struct vnc_session_s *session, int port) +{ + struct sockaddr_in addr; + int ret; + + gvdbg("Connecting display %d\n", session->display); + + /* Create a listening socket */ + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = INADDR_ANY; + + ret = psock_socket(AF_INET, SOCK_STREAM, 0, &session->listen); + if (ret < 0) + { + ret = -get_errno(); + return ret; + } + + /* Bind the listening socket to a local address */ + + ret = psock_bind(&session->listen, (struct sockaddr *)&addr, + sizeof(struct sockaddr_in)); + if (ret < 0) + { + ret = -get_errno(); + goto errout_with_listener; + } + + /* Listen for a connection */ + + ret = psock_listen(&session->listen, 5); + if (ret < 0) + { + ret = -get_errno(); + goto errout_with_listener; + } + + /* Connect to the client */ + + gvdbg("Accepting connection for Display %d\n", session->display); + + ret = psock_accept(&session->listen, NULL, NULL, &session->connect); + if (ret < 0) + { + ret = -get_errno(); + goto errout_with_listener; + } + + gvdbg("Display %d connected\n", session->display); + session->state = VNCSERVER_CONNECTED; + return OK; + +errout_with_listener: + psock_close(&session->listen); + return ret; +} + +/**************************************************************************** + * Pubic Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_server + * + * Description: + * The VNC server daemon. This daemon is implemented as a kernel thread. + * + * Input Parameters: + * Standard kernel thread arguments (all ignored) + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +int vnc_server(int argc, FAR char *argv[]) +{ + FAR struct vnc_session_s *session; + FAR uint8_t *fb; + int display; + int ret; + + /* A single argument is expected: A diplay port number in ASCII form */ + + if (argc != 2) + { + gdbg("ERROR: Unexpected number of arguments: %d\n", argc); + ret = -EINVAL; + goto errout_with_post; + } + + display = atoi(argv[1]); + if (display < 0 || display >= RFB_MAX_DISPLAYS) + { + gdbg("ERROR: Invalid display number: %d\n", display); + ret = -EINVAL; + goto errout_with_post; + } + + gvdbg("Server started for Display %d\n", display); + + /* Allocate the framebuffer memory. We rely on the fact that + * the KMM allocator will align memory to 32-bits or better. + */ + + fb = (FAR uint8_t *)kmm_zalloc(RFB_SIZE); + if (fb == NULL) + { + gdbg("ERROR: Failed to allocate framebuffer memory: %lu KB\n", + (unsigned long)(RFB_SIZE / 1024)); + ret = -ENOMEM; + goto errout_with_post; + } + + /* Allocate a session structure for this display */ + + session = kmm_zalloc(sizeof(struct vnc_session_s)); + if (session == NULL) + { + gdbg("ERROR: Failed to allocate session\n"); + ret = -ENOMEM; + goto errout_with_fb; + } + + g_vnc_sessions[display] = session; + sem_init(&session->freesem, 0, CONFIG_VNCSERVER_NUPDATES); + sem_init(&session->queuesem, 0, 0); + + /* Loop... handling each each VNC client connection to this display. Only + * a single client is allowed for each display. + */ + + for (; ; ) + { + /* Release the last session and [Re-]initialize the session structure + * for the next connection. + */ + + vnc_reset_session(session, fb, display); + g_fbstartup[display].result = -EBUSY; + sem_reset(&g_fbstartup[display].fbsem, 0); + + /* Establish a connection with the VNC client */ + + ret = vnc_connect(session, RFB_DISPLAY_PORT(display)); + if (ret >= 0) + { + gvdbg("New VNC connection\n"); + + /* Perform the VNC initialization sequence after the client has + * sucessfully connected to the server. Negotiate security, + * framebuffer and color properties. + */ + + ret = vnc_negotiate(session); + if (ret < 0) + { + gdbg("ERROR: Failed to negotiate security/framebuffer: %d\n", + ret); + continue; + } + + /* Start the VNC updater thread that sends all Server-to-Client + * messages. + */ + + ret = vnc_start_updater(session); + if (ret < 0) + { + gdbg("ERROR: Failed to start updater thread: %d\n", ret); + continue; + } + + /* Let the framebuffer driver know that we are ready to preform + * updates. + */ + + g_fbstartup[display].result = OK; + sem_post(&g_fbstartup[display].fbsem); + + /* Run the VNC receiver on this trhead. The VNC receiver handles + * all Client-to-Server messages. The VNC receiver function does + * not return until the session has been terminated (or an error + * occurs). + */ + + ret = vnc_receiver(session); + gvdbg("Session terminated with %d\n", ret); + + /* Stop the VNC updater thread. */ + + ret = vnc_stop_updater(session); + if (ret < 0) + { + gdbg("ERROR: Failed to stop updater thread: %d\n", ret); + } + } + } + +errout_with_fb: + kmm_free(fb); + +errout_with_post: + g_fbstartup[display].result = ret; + sem_post(&g_fbstartup[display].fbsem); + 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; +} diff --git a/graphics/vnc/server/vnc_server.h b/graphics/vnc/server/vnc_server.h new file mode 100644 index 00000000000..c4bd08ac38d --- /dev/null +++ b/graphics/vnc/server/vnc_server.h @@ -0,0 +1,417 @@ +/**************************************************************************** + * graphics/vnc/server/vnc_server.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __GRAPHICS_VNC_SERVER_VNC_SERVER_H +#define __GRAPHICS_VNC_SERVER_VNC_SERVER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration */ + +#ifndef CONFIG_NET_TCP_READAHEAD +# error CONFIG_NET_TCP_READAHEAD must be set to use VNC +#endif + +#ifndef CONFIG_NX_UPDATE +# error CONFIG_NX_UPDATE must be set to use VNC +#endif + +#if !defined(CONFIG_VNCSERVER_PROTO3p3) && !defined(CONFIG_VNCSERVER_PROTO3p8) +# error No VNC protocol selected +#endif + +#if defined(CONFIG_VNCSERVER_PROTO3p3) && defined(CONFIG_VNCSERVER_PROTO3p8) +# error Too many VNC protocols selected +#endif + +#ifndef CONFIG_VNCSERVER_NDISPLAYS +# define CONFIG_VNCSERVER_NDISPLAYS 1 +#endif + +#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16) +# define RFB_COLORFMT FB_FMT_RGB16_565 +# define RFB_BITSPERPIXEL 16 +# define RFB_PIXELDEPTH 16 +# define RFB_TRUECOLOR 1 +# define RFB_RMAX 0x1f +# define RFB_GMAX 0x3f +# define RFB_BMAX 0x1f +# define RFB_RSHIFT 11 +# define RFB_GSHIFT 5 +# define RFB_BSHIFT 0 +#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32) +# define RFB_COLORFMT FB_FMT_RGB32 +# define RFB_BITSPERPIXEL 32 +# define RFB_PIXELDEPTH 24 +# define RFB_TRUECOLOR 1 +# define RFB_RMAX 0xff +# define RFB_GMAX 0xff +# define RFB_BMAX 0xff +# define RFB_RSHIFT 16 +# define RFB_GSHIFT 8 +# define RFB_BSHIFT 0 +#else +# error Unspecified/unsupported color format +#endif + +#ifndef CONFIG_VNCSERVER_SCREENWIDTH +# define CONFIG_VNCSERVER_SCREENWIDTH 320 +#endif + +#ifndef CONFIG_VNCSERVER_SCREENHEIGHT +# define CONFIG_VNCSERVER_SCREENHEIGHT 240 +#endif + +#ifndef CONFIG_VNCSERVER_PRIO +# define CONFIG_VNCSERVER_PRIO 100 +#endif + +#ifndef CONFIG_VNCSERVER_STACKSIZE +# define CONFIG_VNCSERVER_STACKSIZE 2048 +#endif + +#ifndef CONFIG_VNCSERVER_UPDATER_PRIO +# define CONFIG_VNCSERVER_UPDATER_PRIO 100 +#endif + +#ifndef CONFIG_VNCSERVER_UPDATER_STACKSIZE +# define CONFIG_VNCSERVER_UPDATER_STACKSIZE 2048 +#endif + +#ifndef CONFIG_VNCSERVER_INBUFFER_SIZE +# define CONFIG_VNCSERVER_INBUFFER_SIZE 80 +#endif + +#ifndef CONFIG_VNCSERVER_NUPDATES +# define CONFIG_VNCSERVER_NUPDATES 48 +#endif + +#ifndef CONFIG_VNCSERVER_UPDATE_BUFSIZE +# define CONFIG_VNCSERVER_UPDATE_BUFSIZE 4096 +#endif + +#define VNCSERVER_UPDATE_BUFSIZE \ + (CONFIG_VNCSERVER_UPDATE_BUFSIZE + SIZEOF_RFB_FRAMEBUFFERUPDATE_S(0)) + +/* Local framebuffer characteristics in bytes */ + +#define RFB_BYTESPERPIXEL ((RFB_BITSPERPIXEL + 7) >> 3) +#define RFB_STRIDE (RFB_BYTESPERPIXEL * CONFIG_VNCSERVER_SCREENWIDTH) +#define RFB_SIZE (RFB_STRIDE * CONFIG_VNCSERVER_SCREENHEIGHT) + +/* RFB Port Number */ + +#define RFB_PORT_BASE 5900 +#define RFB_MAX_DISPLAYS CONFIG_VNCSERVER_NDISPLAYS +#define RFB_DISPLAY_PORT(d) (RFB_PORT_BASE + (d)) + +/* Miscellaneous */ + +#ifndef MIN +# define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This enumeration indicates the state of the VNC server */ + +enum vnc_server_e +{ + VNCSERVER_UNINITIALIZED = 0, /* Initial state */ + VNCSERVER_INITIALIZED, /* State structured initialized, but not connected */ + VNCSERVER_CONNECTED, /* Connect to a client, but not yet configured */ + VNCSERVER_CONFIGURED, /* Configured and ready to transfer graphics */ + VNCSERVER_RUNNING, /* Running and activly transferring graphics */ + VNCSERVER_STOPPING, /* The updater has been asked to stop */ + VNCSERVER_STOPPED /* The updater has stopped */ +}; + +/* This structure is used to queue FrameBufferUpdate event. It includes a + * pointer to support singly linked list. + */ + +struct vnc_fbupdate_s +{ + FAR struct vnc_fbupdate_s *flink; + struct nxgl_rect_s rect; /* The enqueued update rectangle */ +}; + +struct vnc_session_s +{ + /* NX graphics system */ + + NXHANDLE handle; /* NX graphics handle */ + + /* Connection data */ + + struct socket listen; /* Listen socket */ + struct socket connect; /* Connected socket */ + volatile uint8_t state; /* See enum vnc_server_e */ + + /* Display geometry and color characteristics */ + + uint8_t display; /* Display number (for debug) */ + uint8_t colorfmt; /* Remote color format (See include/nuttx/fb.h) */ + uint8_t bpp; /* Remote bits per pixel */ + FAR uint8_t *fb; /* Allocated local frame buffer */ + + /* Updater information */ + + pthread_t updater; /* Updater thread ID */ + + /* Update list information */ + + struct vnc_fbupdate_s updpool[CONFIG_VNCSERVER_NUPDATES]; + sq_queue_t updfree; + sq_queue_t updqueue; + sem_t freesem; + sem_t queuesem; + + /* I/O buffers for misc network send/receive */ + + uint8_t inbuf[CONFIG_VNCSERVER_INBUFFER_SIZE]; + uint8_t outbuf[VNCSERVER_UPDATE_BUFSIZE]; +}; + +/* This structure is used to communicate start-up status between the server + * the framebuffer driver. + */ + +struct fb_startup_s +{ + sem_t fbsem; /* Framebuffer driver will wait on this */ + int16_t result; /* OK: successfully initialized */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* Given a display number as an index, the following array can be used to + * look-up the session structure for that display. + */ + +EXTERN FAR struct vnc_session_s *g_vnc_sessions[RFB_MAX_DISPLAYS]; + +/* Used to synchronize the server thread with the framebuffer driver. */ + +EXTERN struct fb_startup_s g_fbstartup[RFB_MAX_DISPLAYS]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_server + * + * Description: + * The VNC server daemon. This daemon is implemented as a kernel thread. + * + * Input Parameters: + * Standard kernel thread arguments (all ignored) + * + * Returned Value: + * This function does not return. + * + ****************************************************************************/ + +int vnc_server(int argc, FAR char *argv[]); + +/**************************************************************************** + * Name: vnc_negotiate + * + * Description: + * Perform the VNC initialization sequence after the client has sucessfully + * connected to the server. Negotiate security, framebuffer and color + * properties. + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * Returns zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int vnc_negotiate(FAR struct vnc_session_s *session); + +/**************************************************************************** + * Name: vnc_start_updater + * + * Description: + * Start the updater thread + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int vnc_start_updater(FAR struct vnc_session_s *session); + +/**************************************************************************** + * Name: vnc_stop_updater + * + * Description: + * Stop the updater thread + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int vnc_stop_updater(FAR struct vnc_session_s *session); + +/**************************************************************************** + * Name: vnc_update_rectangle + * + * Description: + * Queue an update of the specified rectangular region on the display. + * + * Input Parameters: + * session - An instance of the session structure. + * rect - The rectanglular region to be updated. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int vnc_update_rectangle(FAR struct vnc_session_s *session, + FAR const struct nxgl_rect_s *rect); + +/**************************************************************************** + * Name: vnc_receiver + * + * Description: + * This function handles all Client-to-Server messages. + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * At present, always returns OK + * + ****************************************************************************/ + +int vnc_receiver(FAR struct vnc_session_s *session); + +/**************************************************************************** + * Name: vnc_key_map + * + * Description: + * Map the receive X11 keysym into something understood by NuttX and route + * that through NX to the appropriate window. + * + * Input Parameters: + * session - An instance of the session structure. + * keysym - The X11 keysym value (see include/nuttx/inputx11_keysymdef) + * keydown - True: Key pressed; False: Key released + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NX_KBD +void vnc_key_map(FAR struct vnc_session_s *session, uint16_t keysym, + bool keydown); +#endif + +/**************************************************************************** + * Name: vnc_find_session + * + * Description: + * Return the session structure associated with this display. + * + * Input Parameters: + * display - The display number of interest. + * + * Returned Value: + * Returns the instance of the session structure for this display. NULL + * will be returned if the server has not yet been started or if the + * display number is out of range. + * + ****************************************************************************/ + +FAR struct vnc_session_s *vnc_find_session(int display); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __GRAPHICS_VNC_SERVER_VNC_SERVER_H */ diff --git a/graphics/vnc/server/vnc_updater.c b/graphics/vnc/server/vnc_updater.c new file mode 100644 index 00000000000..01e1046a966 --- /dev/null +++ b/graphics/vnc/server/vnc_updater.c @@ -0,0 +1,856 @@ +/**************************************************************************** + * graphics/vnc/vnc_updater.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "vnc_server.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Color conversion functions */ + +#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16) +typedef CODE uint16_t(*vnc_convert16_t)(uint16_t rgb); +typedef CODE uint32_t(*vnc_convert32_t)(uint16_t rgb); +#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32) +typedef CODE uint16_t(*vnc_convert16_t)(uint32_t rgb); +typedef CODE uint32_t(*vnc_convert32_t)(uint32_t rgb); +#else +# error Unspecified/unsupported color format +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_alloc_update + * + * Description: + * Allocate one update structure by taking it from the freelist. + * + * Input Parameters: + * session - A reference to the VNC session structure. + * + * Returned Value: + * A non-NULL structure pointer should always be returned. This function + * will wait if no structure is available. + * + ****************************************************************************/ + +static FAR struct vnc_fbupdate_s * +vnc_alloc_update(FAR struct vnc_session_s *session) +{ + FAR struct vnc_fbupdate_s *update; + + /* Reserve one element from the free list. Lock the scheduler to assure + * that the sq_remfirst() and the successful return from sem_wait are + * atomic. Of course, the scheduler will be unlocked while we wait. + */ + + sched_lock(); + while (sem_wait(&session->freesem) < 0) + { + DEBUGASSERT(get_errno() == EINTR); + } + + /* It is reserved.. go get it */ + + update = (FAR struct vnc_fbupdate_s *)sq_remfirst(&session->updfree); + sched_unlock(); + + DEBUGASSERT(update != NULL); + return update; +} + +/**************************************************************************** + * Name: vnc_free_update + * + * Description: + * Free one update structure by returning it from the freelist. + * + * Input Parameters: + * session - A reference to the VNC session structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vnc_free_update(FAR struct vnc_session_s *session, + FAR struct vnc_fbupdate_s *update) +{ + /* Reserve one element from the free list. Lock the scheduler to assure + * that the sq_addlast() and the sem_post() are atomic. + */ + + sched_lock(); + + /* Put the entry into the free list */ + + sq_addlast((FAR sq_entry_t *)update, &session->updfree); + + /* Post the semaphore to indicate the availability of one more update */ + + sem_post(&session->freesem); + DEBUGASSERT(session->freesem.semcount <= CONFIG_VNCSERVER_NUPDATES); + + sched_unlock(); +} + +/**************************************************************************** + * Name: vnc_remove_queue + * + * Description: + * Remove one entry from the list of queued rectangles, waiting if + * necessary if the queue is empty. + * + * Input Parameters: + * session - A reference to the VNC session structure. + * + * Returned Value: + * A non-NULL structure pointer should always be returned. This function + * will wait if no structure is available. + * + ****************************************************************************/ + +static FAR struct vnc_fbupdate_s * +vnc_remove_queue(FAR struct vnc_session_s *session) +{ + FAR struct vnc_fbupdate_s *rect; + + /* Reserve one element from the list of queued rectangle. Lock the + * scheduler to assure that the sq_remfirst() and the successful return + * from sem_wait are atomic. Of course, the scheduler will be unlocked + * while we wait. + */ + + sched_lock(); + while (sem_wait(&session->queuesem) < 0) + { + DEBUGASSERT(get_errno() == EINTR); + } + + /* It is reserved.. go get it */ + + rect = (FAR struct vnc_fbupdate_s *)sq_remfirst(&session->updqueue); + sched_unlock(); + + DEBUGASSERT(rect != NULL); + return rect; +} + +/**************************************************************************** + * Name: vnc_add_queue + * + * Description: + * Add one rectangle entry to the list of queued rectangles to be updated. + * + * Input Parameters: + * session - A reference to the VNC session structure. + * rect - The rectangle to be added to the queue. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void vnc_add_queue(FAR struct vnc_session_s *session, + FAR struct vnc_fbupdate_s *rect) +{ + /* Lock the scheduler to assure that the sq_addlast() and the sem_post() + * are atomic. + */ + + sched_lock(); + + /* Put the entry into the list of queued rectangles. */ + + sq_addlast((FAR sq_entry_t *)rect, &session->updqueue); + + /* Post the semaphore to indicate the availability of one more rectangle + * in the queue. This may wakeup the updater. + */ + + sem_post(&session->queuesem); + DEBUGASSERT(session->queuesem.semcount <= CONFIG_VNCSERVER_NUPDATES); + + sched_unlock(); +} + +/**************************************************************************** + * Name: vnc_convert_rgbNN + * + * Description: + * Convert the native framebuffer color format (either RGB16 5:6:5 or RGB32 + * 8:8:8) to the remote framebuffer color format (either RGB16 5:6:5, + * RGB16 5:5:5, or RGB32 8:8:) + * + * Input Parameters: + * pixel - The src color in local framebuffer format. + * + * Returned Value: + * The pixel in the remote framebuffer color format. + * + ****************************************************************************/ + +#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16) + +uint16_t vnc_convert_rgb16_555(uint16_t rgb) +{ + /* 111111 + * 54321098 76543210 + * ----------------- + * RRRRRGGG GGGBBBBB + * .RRRRRGG GGGBBBBB + */ + + return (((rgb >> 1) & ~0x1f) | (rgb & 0x1f)); +} + +uint16_t vnc_convert_rgb16_565(uint16_t rgb) +{ + /* Identity mapping */ + + return rgb; +} + +uint32_t vnc_convert_rgb32_888(uint16_t rgb) +{ + /* 33222222 22221111 111111 + * 10987654 32109876 54321098 76543210 + * ---------------------------------- + * RRRRRGGG GGGBBBBB + * RRRRR... GGGGGG.. BBBBB... + */ + + return (((uint32_t)rgb << 8) & 0x00f80000) | + (((uint32_t)rgb << 6) & 0x0000fc00) | + (((uint32_t)rgb << 3) & 0x000000f8); +} + +#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32) +uint16_t vnc_convert_rgb16_555(uint32_t rgb) +{ + /* 33222222 22221111 111111 + * 10987654 32109876 54321098 76543210 + * ---------------------------------- + * RRRRR... GGGGG... BBBBB... + * .RRRRRGG GGGBBBBB + */ + + return (uint16_t) + (((rgb >> 9) & 0x00007c00) | + ((rgb >> 6) & 0x000003e0) | + ((rgb >> 3) & 0x0000001f)); +} + +uint16_t vnc_convert_rgb16_565(uint32_t rgb) +{ + /* 33222222 22221111 111111 + * 10987654 32109876 54321098 76543210 + * ---------------------------------- + * RRRRR... GGGGGG.. BBBBB... + * RRRRRGGG GGGBBBBB + */ + + return (uint16_t) + (((rgb >> 8) & 0x0000f800) | + ((rgb >> 5) & 0x000007e0) | + ((rgb >> 3) & 0x0000001f)); +} + +uint32_t vnc_convert_rgb32_888(uint32_t rgb) +{ + /* Identity mapping */ + + return rgb; +} +#else +# error Unspecified/unsupported color format +#endif + +/**************************************************************************** + * Name: vnc_copy16 + * + * Description: + * Copy a 16/32-bit pixels from the source rectangle to a 16-bit pixel + * destination rectangle. + * + * Input Parameters: + * session - A reference to the VNC session structure. + * row,col - The upper left X/Y (pixel/row) position of the rectangle + * width,height - The width (pixels) and height (rows of the rectangle) + * convert - The function to use to convert from the local framebuffer + * color format to the remote framebuffer color format. + * + * Returned Value: + * The size of the transfer in bytes. + * + ****************************************************************************/ + +static size_t vnc_copy16(FAR struct vnc_session_s *session, + nxgl_coord_t row, nxgl_coord_t col, + nxgl_coord_t height, nxgl_coord_t width, + vnc_convert16_t convert) +{ +#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16) + FAR struct rfb_framebufferupdate_s *update; + FAR const uint16_t *srcleft; + FAR const uint16_t *src; + FAR uint16_t *dest; + nxgl_coord_t x; + nxgl_coord_t y; + + /* Destination rectangle start address */ + + update = (FAR struct rfb_framebufferupdate_s *)session->outbuf; + dest = (FAR uint16_t *)update->rect[0].data; + + /* Source rectangle start address (left/top)*/ + + srcleft = (FAR uint16_t *)(session->fb + RFB_STRIDE * row + RFB_BYTESPERPIXEL * col); + + /* Transfer each row from the source buffer into the update buffer */ + + for (y = 0; y < height; y++) + { + src = srcleft; + for (x = 0; x < width; x++) + { + *dest++ = convert(*src); + src++; + } + + srcleft = (FAR uint16_t *)((uintptr_t)srcleft + RFB_STRIDE); + } + + return (size_t)((uintptr_t)dest - (uintptr_t)update->rect[0].data); + +#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32) + FAR struct rfb_framebufferupdate_s *update; + FAR const uint32_t *srcleft; + FAR const uint32_t *src; + FAR uint16_t *dest; + nxgl_coord_t x; + nxgl_coord_t y; + + /* Destination rectangle start address */ + + update = (FAR struct rfb_framebufferupdate_s *)session->outbuf; + dest = (FAR uint16_t *)update->rect[0].data; + + /* Source rectangle start address */ + + srcleft = (FAR uint32_t *)(session->fb + RFB_STRIDE * row + RFB_BYTESPERPIXEL * col); + + for (y = 0; y < height; y++) + { + src = srcleft; + for (x = 0; x < width; x++) + { + *dest++ = convert(*src); + src++; + } + + srcleft = (FAR uint32_t *)((uintptr_t)srcleft + RFB_STRIDE); + } + + return (size_t)((uintptr_t)dest - (uintptr_t)update->rect[0].data); +#endif +} + +/**************************************************************************** + * Name: vnc_copy32 + * + * Description: + * Copy a 16/32-bit pixels from the source rectangle to a 32-bit pixel + * destination rectangle. + * + * Input Parameters: + * session - A reference to the VNC session structure. + * row,col - The upper left X/Y (pixel/row) position of the rectangle + * width,height - The width (pixels) and height (rows of the rectangle) + * convert - The function to use to convert from the local framebuffer + * color format to the remote framebuffer color format. + * + * Returned Value: + * The size of the transfer in bytes. + * + ****************************************************************************/ + +static size_t vnc_copy32(FAR struct vnc_session_s *session, + nxgl_coord_t row, nxgl_coord_t col, + nxgl_coord_t height, nxgl_coord_t width, + vnc_convert32_t convert) +{ +#if defined(CONFIG_VNCSERVER_COLORFMT_RGB16) + FAR struct rfb_framebufferupdate_s *update; + FAR const uint16_t *srcleft; + FAR const uint16_t *src; + FAR uint32_t *dest; + nxgl_coord_t x; + nxgl_coord_t y; + + /* Destination rectangle start address */ + + update = (FAR struct rfb_framebufferupdate_s *)session->outbuf; + dest = (FAR uint32_t *)update->rect[0].data; + + /* Source rectangle start address (left/top)*/ + + srcleft = (FAR uint16_t *)(session->fb + RFB_STRIDE * row + RFB_BYTESPERPIXEL * col); + + /* Transfer each row from the source buffer into the update buffer */ + + for (y = 0; y < height; y++) + { + src = srcleft; + for (x = 0; x < width; x++) + { + *dest++ = convert(*src); + src++; + } + + srcleft = (FAR uint16_t *)((uintptr_t)srcleft + RFB_STRIDE); + } + + return (size_t)((uintptr_t)srcleft - (uintptr_t)update->rect[0].data); + +#elif defined(CONFIG_VNCSERVER_COLORFMT_RGB32) + FAR struct rfb_framebufferupdate_s *update; + FAR const uint32_t *srcleft; + FAR const uint32_t *src; + FAR uint32_t *dest; + nxgl_coord_t x; + nxgl_coord_t y; + + /* Destination rectangle start address */ + + update = (FAR struct rfb_framebufferupdate_s *)session->outbuf; + dest = (FAR uint32_t *)update->rect[0].data; + + /* Source rectangle start address */ + + srcleft = (FAR uint32_t *)(session->fb + RFB_STRIDE * row + RFB_BYTESPERPIXEL * col); + + for (y = 0; y < height; y++) + { + src = srcleft; + for (x = 0; x < width; x++) + { + *dest++ = convert(*src); + src++; + } + + srcleft = (FAR uint32_t *)((uintptr_t)srcleft + RFB_STRIDE); + } + + return (size_t)((uintptr_t)srcleft - (uintptr_t)update->rect[0].data); +#endif +} + +/**************************************************************************** + * Name: vnc_updater + * + * Description: + * This is the "updater" thread. It is the sender of all Server-to-Client + * messages + * + * Input Parameters: + * Standard pthread arguments. + * + * Returned Value: + * NULL is always returned. + * + ****************************************************************************/ + +static FAR void *vnc_updater(FAR void *arg) +{ + FAR struct vnc_session_s *session = (FAR struct vnc_session_s *)arg; + FAR struct rfb_framebufferupdate_s *update; + + FAR struct rfb_rectangle_s *destrect; + FAR struct vnc_fbupdate_s *srcrect; + FAR const uint8_t *srcrow; + FAR const uint8_t *src; + nxgl_coord_t srcwidth; + nxgl_coord_t srcheight; + nxgl_coord_t destwidth; + nxgl_coord_t destheight; + nxgl_coord_t deststride; + nxgl_coord_t updwidth; + nxgl_coord_t updheight; + nxgl_coord_t width; + nxgl_coord_t x; + nxgl_coord_t y; + unsigned int bytesperpixel; + unsigned int maxwidth; + size_t size; + ssize_t nsent; + + union + { + vnc_convert16_t bpp16; + vnc_convert32_t bpp32; + } convert; + bool color32 = false; + + DEBUGASSERT(session != NULL); + gvdbg("Updater running for Display %d\n", session->display); + + /* Set up some constant pointers and values */ + + update = (FAR struct rfb_framebufferupdate_s *)session->outbuf; + destrect = update->rect; + + bytesperpixel = (session->bpp + 7) >> 3; + maxwidth = CONFIG_VNCSERVER_UPDATE_BUFSIZE / bytesperpixel; + + /* Set up the color conversion */ + + switch (session->colorfmt) + { + case FB_FMT_RGB16_555: + convert.bpp16 = vnc_convert_rgb16_555; + break; + + case FB_FMT_RGB16_565: + convert.bpp16 = vnc_convert_rgb16_565; + break; + + case FB_FMT_RGB32: + convert.bpp32 = vnc_convert_rgb32_888; + color32 = true; + break; + + default: + gdbg("ERROR: Unrecognized color format: %d\n", session->colorfmt); + goto errout; + } + + /* Then loop, processing updates until we are asked to stop. + * REVISIT: Probably need some kind of signal mechanism to wake up + * vnc_remove_queue() in order to stop. Or perhaps a special STOP + * message in the queue? + */ + + while (session->state == VNCSERVER_RUNNING) + { + /* Get the next queued rectangle update. This call will block until an + * upate is available for the case where the update queue is empty. + */ + + srcrect = vnc_remove_queue(session); + DEBUGASSERT(srcrect != NULL); + + /* Get with width and height of the source and destination rectangles. + * The source rectangle many be larger than the destination rectangle. + * In that case, we will have to emit multiple rectangles. + */ + + DEBUGASSERT(srcrect->rect.pt1.x <= srcrect->rect.pt2.x); + srcwidth = srcrect->rect.pt2.x - srcrect->rect.pt1.x + 1; + + DEBUGASSERT(srcrect->rect.pt1.y <= srcrect->rect.pt2.y); + srcheight = srcrect->rect.pt2.y - srcrect->rect.pt1.y + 1; + + srcrow = session->fb + + RFB_STRIDE * srcrect->rect.pt1.y + + RFB_BYTESPERPIXEL * srcrect->rect.pt1.x; + + deststride = srcwidth * bytesperpixel; + if (deststride > maxwidth) + { + deststride = maxwidth; + } + + destwidth = deststride / bytesperpixel; + destheight = CONFIG_VNCSERVER_UPDATE_BUFSIZE / deststride; + + if (destheight > srcheight) + { + destheight = srcheight; + } + + /* Format the rectangle header. We may have to send several update + * messages if the pre-allocated outbuf is smaller than the rectangle. + * Each update contains a small "sub-rectangle" of the origin update. + * + * Loop until all sub-rectangles have been output. Start with the + * top row and transfer rectangles horizontally across each swath. + * The height of the swath is destwidth (the last may be shorter). + */ + + for (y = srcrect->rect.pt1.y; + srcheight > 0; + srcheight -= updheight, y += updheight, + srcrow += RFB_STRIDE * updheight) + { + /* updheight = Height to update on this pass through the loop. + * This will be destheight unless fewer than that number of rows + * remain. + */ + + updheight = destheight; + if (updheight > srcheight) + { + updheight = srcheight; + } + + /* Loop until this horizontal swath has sent to the VNC client. + * Start with the leftmost pixel and transfer rectangles + * horizontally with width of destwidth until all srcwidth + * columns have been transferred (the last rectangle may be + * narrower). + */ + + for (width = srcwidth, x = srcrect->rect.pt1.x, src = srcrow; + width > 0; + width -= updwidth, x += updwidth, src += updwidth) + { + /* updwidth = Width to update on this pass through the loop. + * This will be destwidth unless fewer than that number of + * columns remain. + */ + + updwidth = destwidth; + if (updwidth > width) + { + updwidth = width; + } + + /* Transfer the frame buffer data into the rectangle, + * performing the necessary color conversions. + */ + + if (color32) + { + size = vnc_copy32(session, y, x, updheight, updwidth, + convert.bpp32); + } + else + { + size = vnc_copy16(session, y, x, updheight, updwidth, + convert.bpp16); + } + + /* Format the FramebufferUpdate message */ + + update->msgtype = RFB_FBUPDATE_MSG; + update->padding = 0; + rfb_putbe16(update->nrect, 1); + + rfb_putbe16(destrect->xpos, x); + rfb_putbe16(destrect->ypos, y); + rfb_putbe16(destrect->width, updwidth); + rfb_putbe16(destrect->height, updheight); + rfb_putbe16(destrect->encoding, RFB_ENCODING_RAW); + + DEBUGASSERT(size <= CONFIG_VNCSERVER_UPDATE_BUFSIZE); + + /* Then send the update packet to the VNC client */ + + size += SIZEOF_RFB_FRAMEBUFFERUPDATE_S(0); + nsent = psock_send(&session->connect, session->outbuf, size, 0); + if (nsent < 0) + { + gdbg("ERROR: Send FrameBufferUpdate failed: %d\n", + get_errno()); + goto errout; + } + + DEBUGASSERT(nsent == size); + } + } + + vnc_free_update(session, srcrect); + } + +errout: + session->state = VNCSERVER_STOPPED; + return NULL; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vnc_start_updater + * + * Description: + * Start the updater thread + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int vnc_start_updater(FAR struct vnc_session_s *session) +{ + pthread_attr_t attr; + struct sched_param param; + int status; + + gvdbg("Starting updater for Display %d\n", session->display); + + /* Create thread that is gonna send rectangles to the client */ + + session->state = VNCSERVER_RUNNING; + + DEBUGVERIFY(pthread_attr_init(&attr)); + DEBUGVERIFY(pthread_attr_setstacksize(&attr, CONFIG_VNCSERVER_UPDATER_STACKSIZE)); + + param.sched_priority = CONFIG_VNCSERVER_UPDATER_PRIO; + DEBUGVERIFY(pthread_attr_setschedparam(&attr, ¶m)); + + status = pthread_create(&session->updater, &attr, vnc_updater, + (pthread_addr_t)session); + if (status != 0) + { + return -status; + } + + return OK; +} + +/**************************************************************************** + * Name: vnc_stop_updater + * + * Description: + * Stop the updater thread + * + * Input Parameters: + * session - An instance of the session structure. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int vnc_stop_updater(FAR struct vnc_session_s *session) +{ + pthread_addr_t result; + int status; + + /* Is the update thread running? */ + + if (session->state == VNCSERVER_RUNNING) + { + /* Yes.. ask it to please stop */ + + session->state = VNCSERVER_STOPPING; + + /* Wait for the thread to comply with our request */ + + status = pthread_join(session->updater, &result); + if (status != 0) + { + return -status; + } + + /* Return what the thread returned */ + + return (int)((intptr_t)result); + } + + /* Not running? Just say we stopped the thread successfully. */ + + return OK; +} + +/**************************************************************************** + * Name: vnc_update_rectangle + * + * Description: + * Queue an update of the specified rectangular region on the display. + * + * Input Parameters: + * session - An instance of the session structure. + * rect - The rectanglular region to be updated. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int vnc_update_rectangle(FAR struct vnc_session_s *session, + FAR const struct nxgl_rect_s *rect) +{ + FAR struct vnc_fbupdate_s *update; + + /* Make sure that the rectangle has a area */ + + if (!nxgl_nullrect(rect)) + { + /* Allocate an update structure... waiting if necessary */ + + update = vnc_alloc_update(session); + DEBUGASSERT(update != NULL); + + /* Copy the rectangle into the update structure */ + + memcpy(&update->rect, rect, sizeof(struct nxgl_rect_s)); + + /* Add the upate to the end of the update queue. */ + + vnc_add_queue(session, update); + } + + return -ENOSYS; +} diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c index a6921315fd1..01259753933 100644 --- a/net/socket/recvfrom.c +++ b/net/socket/recvfrom.c @@ -261,7 +261,7 @@ static inline void recvfrom_newtcpdata(FAR struct net_driver_s *dev, size_t recvlen = recvfrom_newdata(dev, pstate); - /* If there is more data left in the packet that we could not buffer, than + /* If there is more data left in the packet that we could not buffer, then * add it to the read-ahead buffers. */ diff --git a/sched/task/task_create.c b/sched/task/task_create.c index 1cc59793ccc..c8dc768d5ab 100644 --- a/sched/task/task_create.c +++ b/sched/task/task_create.c @@ -117,12 +117,14 @@ static int thread_create(FAR const char *name, uint8_t ttype, int priority, #endif #if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0 +#if 0 /* No... there are side effects */ /* Associate file descriptors with the new task. Exclude kernel threads; * kernel threads do not have file or socket descriptors. They must use * SYSLOG for output and the low-level psock interfaces for network I/O. */ if (ttype != TCB_FLAG_TTYPE_KERNEL) +#endif { ret = group_setuptaskfiles(tcb); if (ret < OK)