This commit adds a test example at apps/examples/pwfb that will be used for testing the per-window framebuffer feature. The test does not work correctly yet.

Squashed commit of the following:

    apps/examples/pwfb:  Fixes compile and early debug issues.

    apps/examples/pwfb:  Code complete!

    apps/examples/pwfb:  Flesh out the motion logic.

    apps/examples/pwfb:  Add an example/test case that will, eventually be used verify the per-window framebuffer logic.  This is not even code complete at this point.
This commit is contained in:
Gregory Nutt 2019-03-16 12:27:45 -06:00
parent d33ce2c3ae
commit 98b4394c9d
8 changed files with 1421 additions and 0 deletions

11
examples/pwfb/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/Make.dep
/.depend
/.built
/*.asm
/*.obj
/*.rel
/*.lst
/*.sym
/*.adb
/*.lib
/*.src

93
examples/pwfb/Kconfig Normal file
View File

@ -0,0 +1,93 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_PWFB
tristate "NX Per-Window Framebuffer Example"
default n
depends on NX
select LIB_BOARDCTL
select NX_RAMBACKED
---help---
Enable the NX per-window framebuffer example
if EXAMPLES_PWFB
config EXAMPLES_PWFB_DEFAULT_COLORS
bool "Use Default Colors"
default y
if !EXAMPLES_PWFB_DEFAULT_COLORS
config EXAMPLES_PWFB_BGCOLOR
hex "Background Color"
---help---
The color of the background. Default depends on config EXAMPLES_PWFB_BPP.
config EXAMPLES_PWFB_COLOR1
hex "Color of Window 1"
---help---
The color of window 1. Default depends on config EXAMPLES_PWFB_BPP.
config EXAMPLES_PWFB_COLOR2
hex "Color of Window 2"
---help---
The color of window 2. Default depends on config EXAMPLES_PWFB_BPP.
config EXAMPLES_PWFB_COLOR3
hex "Color of Window 3"
---help---
The color of window 3. Default depends on config EXAMPLES_PWFB_BPP.
config EXAMPLES_PWFB_FONTCOLOR
hex "Font Color"
---help---
The color of the fonts. Default depends on config EXAMPLES_PWFB_BPP.
endif
config EXAMPLES_PWFB_DEFAULT_FONT
bool "Use Default Font"
default y
config EXAMPLES_PWFB_FONTID
int "Font ID"
depends on !EXAMPLES_PWFB_DEFAULT_FONT
---help---
Selects the font (see font ID numbers in include/nuttx/nx/nxfonts.h)
config EXAMPLES_PWFB_BPP
int "Bits-Per-Pixel"
default 32
---help---
Pixels per pixel to use. Valid options include 2, 4, 8, 16, 24,
and 32. Default is 32.
comment "NX Server Options"
config EXAMPLES_PWFB_STACKSIZE
int "NX Server Stack Size"
default 2048
---help---
The stacksize to use when creating the NX server. Default 2048
config EXAMPLES_PWFB_CLIENTPRIO
int "Client Priority"
default 100
---help---
The client priority. Default: 100
config EXAMPLES_PWFB_SERVERPRIO
int "Server Priority"
default 120
---help---
The server priority. Default: 120
config EXAMPLES_PWFB_LISTENERPRIO
int "Listener Priority"
default 80
---help---
The priority of the event listener thread. Default 80.
endif

39
examples/pwfb/Make.defs Normal file
View File

@ -0,0 +1,39 @@
############################################################################
# apps/examples/pwfb/Make.defs
# Adds selected applications to apps/ build
#
# Copyright (C) 2019 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifneq ($(CONFIG_EXAMPLES_PWFB),)
CONFIGURED_APPS += examples/pwfb
endif

55
examples/pwfb/Makefile Normal file
View File

@ -0,0 +1,55 @@
############################################################################
# apps/examples/pwfb/Makefile
#
# Copyright (C) 2019 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/Make.defs
# NuttX NX Graphics Example.
ASRCS =
CSRCS = pwfb_events.c pwfb_motion.c
MAINSRC = pwfb_main.c
CONFIG_PWFB_PROGNAME ?= pwfb$(EXEEXT)
PROGNAME = $(CONFIG_PWFB_PROGNAME)
# NX built-in application info
APPNAME = pwfb
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
MODULE = CONFIG_EXAMPLES_PWFB
include $(APPDIR)/Application.mk

181
examples/pwfb/pwfb_events.c Normal file
View File

@ -0,0 +1,181 @@
/****************************************************************************
* examples/pwfb/pwfb_events.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxtk.h>
#include "pwfb_internal.h"
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static void pwfb_redraw(NXTKWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
bool morem, FAR void *arg);
static void pwfb_position(NXTKWINDOW hwnd, FAR const struct nxgl_size_s *size,
FAR const struct nxgl_point_s *pos,
FAR const struct nxgl_rect_s *bounds,
FAR void *arg);
/****************************************************************************
* Public Data
****************************************************************************/
const struct nx_callback_s g_pwfb_cb =
{
pwfb_redraw, /* redraw */
pwfb_position /* position */
#ifdef CONFIG_NX_XYINPUT
, NULL /* mousein */
#endif
#ifdef CONFIG_NX_KBD
, NULL /* kbdin */
#endif
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pwfb_redraw
****************************************************************************/
static void pwfb_redraw(NXTKWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
bool more, FAR void *arg)
{
/* There should be no redraw requests when using per-window framebuffers */
printf("pwfb_redraw: hwnd=%p rect={(%d,%d),(%d,%d)} more=%s\n",
hwnd,
rect->pt1.x, rect->pt1.y, rect->pt2.x, rect->pt2.y,
more ? "true" : "false");
}
/****************************************************************************
* Name: pwfb_position
****************************************************************************/
static void pwfb_position(NXTKWINDOW hwnd, FAR const struct nxgl_size_s *size,
FAR const struct nxgl_point_s *pos,
FAR const struct nxgl_rect_s *bounds,
FAR void *arg)
{
FAR struct pwfb_state_s *st = (FAR struct pwfb_state_s *)arg;
/* Report the position */
printf("pwfb_position: hwnd=%p size=(%d,%d) pos=(%d,%d) "
"bounds={(%d,%d),(%d,%d)}\n",
hwnd, size->w, size->h, pos->x, pos->y,
bounds->pt1.x, bounds->pt1.y, bounds->pt2.x, bounds->pt2.y);
/* Have we picked off the window bounds yet? */
if (!st->haveres)
{
/* Save the window limits (these should be the same for all places and
* all windows.
*/
st->xres = bounds->pt2.x + 1;
st->yres = bounds->pt2.y + 1;
st->haveres = true;
sem_post(&st->semevent);
printf("pwfb_position2: Have xres=%d yres=%d\n", st->xres, st->yres);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwfb_listener
****************************************************************************/
FAR void *pwfb_listener(FAR void *arg)
{
FAR struct pwfb_state_s *st = (FAR struct pwfb_state_s *)arg;
int ret;
/* Process events forever */
for (; ; )
{
/* Handle the next event. If we were configured blocking, then
* we will stay right here until the next event is received. Since
* we have dedicated a while thread to servicing events, it would
* be most natural to also select CONFIG_NX_BLOCKING -- if not, the
* following would be a tight infinite loop (unless we added addition
* logic with nx_eventnotify and sigwait to pace it).
*/
ret = nx_eventhandler(st->hnx);
if (ret < 0)
{
/* An error occurred... assume that we have lost connection with
* the server.
*/
printf("pwfb_listener: Lost server connection: %d\n", errno);
pthread_exit(NULL);
}
/* If we received a message, we must be connected */
if (!st->connected)
{
st->connected = true;
sem_post(&st->semevent);
printf("pwfb_listener: Connected\n");
}
}
}

View File

@ -0,0 +1,192 @@
/****************************************************************************
* examples/pwfb/pwfb_internal.h
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __EXAMPLES_PWFB_PWFB_INTERNAL_H
#define __EXAMPLES_PWFB_PWFB_INTERNAL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <semaphore.h>
#include <fixedmath.h>
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxtk.h>
#include <nuttx/nx/nxfonts.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Required NX Server Settings */
#ifndef CONFIG_NX
# error "NX is not enabled (CONFIG_NX)"
#endif
#ifdef CONFIG_DISABLE_MQUEUE
# error "The multi-threaded example requires MQ support (CONFIG_DISABLE_MQUEUE=n)"
#endif
#ifdef CONFIG_DISABLE_PTHREAD
# error "This example requires pthread support (CONFIG_DISABLE_PTHREAD=n)"
#endif
#ifndef CONFIG_NX_BLOCKING
# error "This example depends on CONFIG_NX_BLOCKING"
#endif
/* Default colors */
#ifndef CONFIG_EXAMPLES_PWFB_BGCOLOR
# if CONFIG_EXAMPLES_PWFB_BPP == 24 || CONFIG_EXAMPLES_PWFB_BPP == 32
# define CONFIG_EXAMPLES_PWFB_BGCOLOR 0x007b68ee
# elif CONFIG_EXAMPLES_PWFB_BPP == 16
# define CONFIG_EXAMPLES_PWFB_BGCOLOR 0x7b5d
# else
# define CONFIG_EXAMPLES_PWFB_BGCOLOR ' '
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWFB_COLOR1
# if CONFIG_EXAMPLES_PWFB_BPP == 24 || CONFIG_EXAMPLES_PWFB_BPP == 32
# define CONFIG_EXAMPLES_PWFB_COLOR1 0x00e6e6fa
# elif CONFIG_EXAMPLES_PWFB_BPP == 16
# define CONFIG_EXAMPLES_PWFB_COLOR1 0xe73f
# else
# define CONFIG_EXAMPLES_PWFB_COLOR1 '1'
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWFB_COLOR2
# if CONFIG_EXAMPLES_PWFB_BPP == 24 || CONFIG_EXAMPLES_PWFB_BPP == 32
# define CONFIG_EXAMPLES_PWFB_COLOR2 0x00dcdcdc
# elif CONFIG_EXAMPLES_PWFB_BPP == 16
# define CONFIG_EXAMPLES_PWFB_COLOR2 0xdefb
# else
# define CONFIG_EXAMPLES_PWFB_COLOR2 '2'
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWFB_COLOR3
# if CONFIG_EXAMPLES_PWFB_BPP == 24 || CONFIG_EXAMPLES_PWFB_BPP == 32
# define CONFIG_EXAMPLES_PWFB_COLOR2 0x00ffecb3
# elif CONFIG_EXAMPLES_PWFB_BPP == 16
# define CONFIG_EXAMPLES_PWFB_COLOR2 0xff76
# else
# define CONFIG_EXAMPLES_PWFB_COLOR2 '3'
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWFB_FONTCOLOR
# if CONFIG_EXAMPLES_PWFB_BPP == 24 || CONFIG_EXAMPLES_PWFB_BPP == 32
# define CONFIG_EXAMPLES_PWFB_FONTCOLOR 0x00000000
# elif CONFIG_EXAMPLES_PWFB_BPP == 16
# define CONFIG_EXAMPLES_PWFB_FONTCOLOR 0x0000
# else
# define CONFIG_EXAMPLES_PWFB_FONTCOLOR 'F'
# endif
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* Describes the unique state of one window */
struct pwfb_window_s
{
NXTKWINDOW hwnd; /* Window handle */
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]; /* Window color */
FCACHE fcache; /* Font cache handle */
b32_t xmax; /* Max X position */
b32_t ymax; /* Max Y position */
b32_t xpos; /* Current X position */
b32_t ypos; /* Current Y position */
b32_t deltax; /* Current X speed */
b32_t deltay; /* Current Y speed */
};
/* Describes the overall state of the example */
struct pwfb_state_s
{
/* NX server */
volatile bool haveres; /* True: Have screen resolution */
volatile bool connected; /* True: Connected to server */
sem_t semevent; /* Event wait semaphore */
NXHANDLE hnx; /* Connection handle */
/* Font */
NXHANDLE hfont; /* The font handle */
/* Graphics hardware */
nxgl_coord_t xres; /* Horizontal resolution */
nxgl_coord_t yres; /* Vertical resolution */
/* Font properties */
uint8_t fheight; /* Max height of a font in pixels */
uint8_t fwidth; /* Max width of a font in pixels */
uint8_t spwidth; /* The width of a space */
/* Window-specific state */
struct pwfb_window_s wndo[3];
};
/****************************************************************************
* Public Data
****************************************************************************/
/* NX callback vtables */
extern const struct nx_callback_s g_pwfb_cb;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR void *pwfb_listener(FAR void *arg);
bool pwfb_motion(FAR struct pwfb_state_s *st);
#endif /* __EXAMPLES_PWFB_PWFB_INTERNAL_H */

685
examples/pwfb/pwfb_main.c Normal file
View File

@ -0,0 +1,685 @@
/****************************************************************************
* examples/pwfb/pwfb_main.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/boardctl.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <pthread.h>
#include <fixedmath.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#ifdef CONFIG_VNCSERVER
# include <nuttx/video/vnc.h>
#endif
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxtk.h>
#include <nuttx/nx/nxbe.h>
#include <nuttx/nx/nxfonts.h>
#include "pwfb_internal.h"
/****************************************************************************
* Private Data
****************************************************************************/
static const char g_wndomsg1[] = "NuttX is cool!";
static const char g_wndomsg2[] = "NuttX is fun!";
static const char g_wndomsg3[] = "NuttX is groovy!";
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pwfb_server_initialize
****************************************************************************/
static bool pwfb_server_initialize(FAR struct pwfb_state_s *st)
{
struct sched_param param;
int ret;
/* Set the client task priority */
param.sched_priority = CONFIG_EXAMPLES_PWFB_CLIENTPRIO;
ret = sched_setparam(0, &param);
if (ret < 0)
{
printf("pwfb_server_initialize: ERROR: "
"sched_setparam failed: %d\n" ,
ret);
return false;
}
/* Start the NX server kernel thread */
ret = boardctl(BOARDIOC_NX_START, 0);
if (ret < 0)
{
printf("pwfb_server_initialize: ERROR: "
"Failed to start the NX server: %d\n",
errno);
return false;
}
/* Connect to the server */
st->hnx = nx_connect();
if (st->hnx)
{
#ifdef CONFIG_VNCSERVER
/* Setup the VNC server to support keyboard/mouse inputs */
ret = vnc_default_fbinitialize(0, st->hnx);
if (ret < 0)
{
printf("pwfb_server_initialize: ERROR: "
"vnc_default_fbinitialize failed: %d\n",
ret);
nx_disconnect(st->hnx);
return false;
}
#endif
}
else
{
printf("pwfb_server_initialize: ERROR: "
"nx_connect failed: %d\n",
errno);
return false;
}
return true;
}
/****************************************************************************
* Name: pwfb_listener_initialize
****************************************************************************/
static bool pwfb_listener_initialize(FAR struct pwfb_state_s *st)
{
struct sched_param param;
pthread_attr_t attr;
pthread_t thread;
int ret;
/* Start a separate thread to listen for server events. This is probably
* the least efficient way to do this, but it makes this example flow more
* smoothly.
*/
(void)pthread_attr_init(&attr);
param.sched_priority = CONFIG_EXAMPLES_PWFB_LISTENERPRIO;
(void)pthread_attr_setschedparam(&attr, &param);
(void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_PWFB_STACKSIZE);
ret = pthread_create(&thread, &attr, pwfb_listener, st);
if (ret != 0)
{
printf("pwfb_listener_initialize: ERROR: "
"pthread_create failed: %d\n",
ret);
return false;
}
/* Don't return until we are connected to the server */
while (!st->connected)
{
/* Wait for the listener thread to wake us up when we really
* are connected.
*/
(void)sem_wait(&st->semevent);
}
return true;
}
/****************************************************************************
* Name: pwfb_state_initialize
****************************************************************************/
static bool pwfb_state_initialize(FAR struct pwfb_state_s *st)
{
FAR const struct nx_font_s *fontset;
/* Initialize semaphores */
sem_init(&st->semevent, 0, 0);
/* Initialize color information */
st->wndo[0].color[0] = CONFIG_EXAMPLES_PWFB_COLOR1;
st->wndo[1].color[0] = CONFIG_EXAMPLES_PWFB_COLOR2;
st->wndo[2].color[0] = CONFIG_EXAMPLES_PWFB_COLOR3;
/* Connect each widnow to the font cache. They cannot share the
* font cache becuse of the differing background colors.
*/
st->wndo[0].fcache = nxf_cache_connect(CONFIG_EXAMPLES_PWFB_FONTID,
CONFIG_EXAMPLES_PWFB_FONTCOLOR,
CONFIG_EXAMPLES_PWFB_COLOR1,
CONFIG_EXAMPLES_PWFB_BPP, 8);
if (st->wndo[0].fcache == NULL)
{
printf("pwfb_state_initialize: ERROR: "
"Failed to connect to font cache for window 1,"
"font ID %d: %d\n",
CONFIG_EXAMPLES_PWFB_FONTID, errno);
return false;
}
st->wndo[1].fcache = nxf_cache_connect(CONFIG_EXAMPLES_PWFB_FONTID,
CONFIG_EXAMPLES_PWFB_FONTCOLOR,
CONFIG_EXAMPLES_PWFB_COLOR2,
CONFIG_EXAMPLES_PWFB_BPP, 8);
if (st->wndo[1].fcache == NULL)
{
printf("pwfb_state_initialize: ERROR: "
"Failed to connect to font cache for window 2,"
"font ID %d: %d\n",
CONFIG_EXAMPLES_PWFB_FONTID, errno);
goto errout_with_fcache1;
}
st->wndo[2].fcache = nxf_cache_connect(CONFIG_EXAMPLES_PWFB_FONTID,
CONFIG_EXAMPLES_PWFB_FONTCOLOR,
CONFIG_EXAMPLES_PWFB_COLOR3,
CONFIG_EXAMPLES_PWFB_BPP, 8);
if (st->wndo[2].fcache == NULL)
{
printf("pwfb_state_initialize: ERROR: "
"Failed to connect to font cache for window 3,"
"font ID %d: %d\n",
CONFIG_EXAMPLES_PWFB_FONTID, errno);
goto errout_with_fcache2;
}
/* Get the handle of the font managed by the font caches. Since the
* font is used, the same font handle can be shared.
*/
st->hfont = nxf_cache_getfonthandle(st->wndo[0].fcache);
if (st->hfont == NULL)
{
printf("pwfb_state_initialize: ERROR: "
"Failed to get handle for font ID %d: %d\n",
CONFIG_EXAMPLES_PWFB_FONTID, errno);
goto errout_with_fcache3;
}
/* Get information about the font set being used and save this in the
* state structure
*/
fontset = nxf_getfontset(st->hfont);
st->fheight = fontset->mxheight;
st->fwidth = fontset->mxwidth;
st->spwidth = fontset->spwidth;
return true;
errout_with_fcache3:
nxf_cache_disconnect(st->wndo[2].fcache);
errout_with_fcache2:
nxf_cache_disconnect(st->wndo[1].fcache);
errout_with_fcache1:
nxf_cache_disconnect(st->wndo[0].fcache);
return false;
}
/****************************************************************************
* Name: pwfb_putc
****************************************************************************/
static bool pwfb_putc(FAR struct pwfb_state_s *st,
FAR struct pwfb_window_s *wndo,
FAR struct nxgl_point_s *fpos,
uint8_t ch)
{
FAR const struct nxfonts_glyph_s *glyph;
FAR const struct nx_fontbitmap_s *fbm;
struct nxgl_rect_s bounds;
struct nxgl_size_s fsize;
FAR const void *src;
int ret;
/* Find (or create) the matching glyph */
glyph = nxf_cache_getglyph(wndo->fcache, ch);
if (glyph == NULL)
{
/* No, there is no font for this code. Treat it like a space. */
fpos->x += st->spwidth;
return true;
}
/* Get information about the glyph? */
fbm = nxf_getbitmap(st->hfont, ch);
if (fbm == NULL)
{
/* Should not happen ceause we already know that the character has a
* glyph.
*/
fpos->x += st->spwidth;
return true;
}
/* Get the font size */
fsize.w = fbm->metric.width + fbm->metric.xoffset;
fsize.h = fbm->metric.height + fbm->metric.yoffset;
/* Construct a bounding box for the glyph */
bounds.pt1.x = fpos->x;
bounds.pt1.y = fpos->y;
bounds.pt2.x = fpos->x + fsize.w - 1;
bounds.pt2.y = fpos->y + fsize.h - 1;
/* Render the glyph into the window */
src = (FAR const void *)glyph->bitmap;
ret = nxtk_bitmapwindow(wndo->hwnd, &bounds, &src,
fpos, (unsigned int)glyph->stride);
if (ret < 0)
{
printf("pwfb_putc: ERROR: "
"nxtk_bitmapwindow failed: %d\n",
errno);
return false;
}
/* Set up the next character position */
fpos->x += glyph->width;
return true;
}
/****************************************************************************
* Name: pwfb_configure_window
****************************************************************************/
static bool pwfb_configure_window(FAR struct pwfb_state_s *st, int wndx,
FAR struct nxgl_size_s *size,
FAR struct nxgl_point_s *pos,
FAR const char *text,
double deltax, double deltay)
{
FAR struct pwfb_window_s *wndo = &st->wndo[wndx];
FAR const char *ptr;
struct nxgl_rect_s rect;
struct nxgl_point_s textpos;
int ret;
/* Set the size of the window */
printf("pwfb_configure_window: Set window %d size to (%d,%d)\n",
wndx + 1, size->w, size->h);
ret = nxtk_setsize(wndo->hwnd, size);
if (ret < 0)
{
printf("pwfb_configure_window: ERROR: "
"nx_setsize failed: %d\n", errno);
goto errout_with_hwnd;
}
/* Set the position of window */
printf("pwfb_configure_window: Set window %d position to (%d,%d)\n",
wndx + 1, pos->x, pos->y);
ret = nxtk_setposition(wndo->hwnd, pos);
if (ret < 0)
{
printf("pwfb_configure_window: ERROR: "
"nxtk_setposition failed: %d\n",
errno);
goto errout_with_hwnd;
}
/* Create a bounding box. This is actually too large because it does not
* account for the boarder widths. However, NX should clip the fill to
* stay within the frame.
*/
rect.pt1.x = 0;
rect.pt1.y = 0;
rect.pt2.x = size->w - 1;
rect.pt2.y = size->h - 1;
/* Fill the window with the selected color */
ret = nxtk_fillwindow(wndo->hwnd, &rect, wndo->color);
if (ret < 0)
{
printf("pwfb_configure_window: ERROR: "
"nxtk_fillwindow failed: %d\n",
errno);
goto errout_with_hwnd;
}
/* Add the text to the display, character at a time */
textpos.x = st->spwidth;
textpos.y = st->fheight;
for (ptr = text; *ptr != '\0'; ptr++)
{
if (!pwfb_putc(st, wndo, &textpos, (uint8_t)*ptr))
{
printf("pwfb_configure_window: ERROR: "
"pwfb_putc failed\n");
goto errout_with_hwnd;
}
}
/* Set up for motion */
wndo->xmax = itob32(st->xres - size->w - 1);
wndo->ymax = itob32(st->yres - size->h - 1);
wndo->ypos = itob32(pos->y);
wndo->xpos = itob32(pos->x);
wndo->deltax = dtob32(deltax);
wndo->deltay = dtob32(deltay);
return true;
errout_with_hwnd:
printf("pwfb_configure_window: Close window %d\n", wndx + 1);
ret = nxtk_closewindow(wndo->hwnd);
if (ret < 0)
{
printf("pwfb_configure_window: ERROR: "
"nxtk_closewindow failed: %d\n",
errno);
}
return false;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwfb_main
****************************************************************************/
#ifdef BUILD_MODULE
int main(int argc, FAR char *argv[])
#else
int pwfb_main(int argc, char *argv[])
#endif
{
struct pwfb_state_s wstate;
struct nxgl_size_s size;
struct nxgl_point_s pos;
nxgl_mxpixel_t color;
int errcode = EXIT_SUCCESS;
int ret;
/* Connect to the NX server */
memset(&wstate, 0, sizeof(struct pwfb_state_s));
if (!pwfb_server_initialize(&wstate) || wstate.hnx == NULL)
{
printf("pwfb_main: ERROR: "
"Failed to get NX handle\n");
goto errout;
}
printf("pwfb_main: NX handle=%p\n", wstate.hnx);
/* Start the listener thread */
if (!pwfb_listener_initialize(&wstate))
{
printf("pwfb_main: ERROR: "
"pwfb_listener_initialize failed\n");
goto errout_with_nx;
}
/* Initialize the window state, colors, font cache, etc. */
if (!pwfb_state_initialize(&wstate))
{
printf("pwfb_main: ERROR: "
"pwfb_state_initialize failed\n");
goto errout_with_nx;
}
/* Set the background to the configured background color */
printf("pwfb_main: Set background color=%d\n",
CONFIG_EXAMPLES_PWFB_BGCOLOR);
color = CONFIG_EXAMPLES_PWFB_BGCOLOR;
ret = nx_setbgcolor(wstate.hnx, &color);
if (ret < 0)
{
printf("pwfb_main: nx_setbgcolor failed: %d\n", errno);
goto errout_with_fontcache;
}
/* Open window 1 */
printf("pwfb_main: Open window 1\n");
wstate.wndo[0].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED,
&g_pwfb_cb, (FAR void *)&wstate);
if (wstate.wndo[0].hwnd == NULL)
{
printf("pwfb_main: ERROR: "
"nxtk_openwindow failed: %d\n",
errno);
goto errout_with_fontcache;
}
printf("pwfb_main: hwnd1=%p\n", wstate.wndo[0].hwnd);
/* Wait until we receive the screen resolution from the server. We only
* need to do this once after opening the first window.
*/
while (!wstate.haveres)
{
(void)sem_wait(&wstate.semevent);
}
printf("pwfb_main: Screen resolution (%d,%d)\n",
wstate.xres, wstate.yres);
/* Configure window 1 */
size.w = wstate.xres / 2;
size.h = wstate.yres / 2;
pos.x = wstate.xres / 4;
pos.y = wstate.yres / 4;
if (!pwfb_configure_window(&wstate, 0, &size, &pos, g_wndomsg1, 1.58, 4.5))
{
printf("pwfb_main: ERROR: "
"pwfb_configure_window failed for window 1\n");
goto errout_with_fontcache;
}
/* Open window 2 */
printf("pwfb_main: Open window 2\n");
wstate.wndo[1].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED,
&g_pwfb_cb, (FAR void *)&wstate);
if (wstate.wndo[1].hwnd == NULL)
{
printf("pwfb_main: ERROR: "
"nxtk_openwindow failed: %d\n",
errno);
goto errout_with_hwnd1;
}
printf("pwfb_main: hwnd1=%p\n", wstate.wndo[1].hwnd);
/* Configure window 2 (same size) */
pos.x = wstate.xres / 4;
pos.y = wstate.yres / 4;
if (!pwfb_configure_window(&wstate, 1, &size, &pos, g_wndomsg2, -1.13, 5.0))
{
printf("pwfb_main: ERROR: "
"pwfb_configure_window failed for window 2\n");
goto errout_with_hwnd2;
}
/* Open window 3 */
printf("pwfb_main: Open window 3\n");
wstate.wndo[2].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED,
&g_pwfb_cb, (FAR void *)&wstate);
if (wstate.wndo[2].hwnd == NULL)
{
printf("pwfb_main: ERROR: "
"nxtk_openwindow failed: %d\n",
errno);
goto errout_with_hwnd2;
}
printf("pwfb_main: hwnd2=%p\n", wstate.wndo[2].hwnd);
/* Configure window 3 (same size) */
pos.x = (3 * wstate.xres) / 8;
pos.y = (3 * wstate.yres) / 8;
if (!pwfb_configure_window(&wstate, 2, &size, &pos, g_wndomsg3, -1.13, 5.0))
{
printf("pwfb_main: ERROR: "
"pwfb_configure_window failed for window 2\n");
goto errout_with_hwnd3;
}
/* Now loop animating the windows */
for (; ; )
{
if (!pwfb_motion(&wstate))
{
printf("pwfb_main: ERROR:"
"pwfb_motion failed\n");
goto errout_with_hwnd3;
}
}
errcode = EXIT_SUCCESS;
/* Close window 3 */
errout_with_hwnd3:
printf("pwfb_main: Close window #2\n");
ret = nxtk_closewindow(wstate.wndo[2].hwnd);
if (ret < 0)
{
printf("pwfb_main: ERROR: nxtk_closewindow failed: %d\n", errno);
}
/* Close window 2 */
errout_with_hwnd2:
printf("pwfb_main: Close window #2\n");
ret = nxtk_closewindow(wstate.wndo[1].hwnd);
if (ret < 0)
{
printf("pwfb_main: ERROR: nxtk_closewindow failed: %d\n", errno);
}
/* Close window1 */
errout_with_hwnd1:
printf("pwfb_main: Close window #1\n");
ret = nxtk_closewindow(wstate.wndo[0].hwnd);
if (ret < 0)
{
printf("pwfb_main: ERROR: nxtk_closewindow failed: %d\n", errno);
}
errout_with_fontcache:
/* Release the font cache */
nxf_cache_disconnect(wstate.wndo[0].fcache);
nxf_cache_disconnect(wstate.wndo[1].fcache);
nxf_cache_disconnect(wstate.wndo[2].fcache);
errout_with_nx:
/* Disconnect from the server */
printf("pwfb_main: Disconnect from the server\n");
nx_disconnect(wstate.hnx);
errout:
return errcode;
}

165
examples/pwfb/pwfb_motion.c Normal file
View File

@ -0,0 +1,165 @@
/****************************************************************************
* examples/pwfb/pwfb_motion.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nxtk.h>
#include "pwfb_internal.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pwfb_move_window
****************************************************************************/
static inline bool pwfb_move_window(FAR struct pwfb_state_s *st, int wndx)
{
FAR struct pwfb_window_s *wndo = &st->wndo[wndx];
FAR struct nxgl_point_s pos;
b32_t newx;
b32_t newy;
bool hit = false;
int ret;
/* Update X position */
newx = wndo->xpos + wndo->deltax;
/* Check for collision with left or right side */
if (newx <= 0)
{
newx = 0;
wndo->deltax = -wndo->deltax;
hit = true;
}
else if (newx >= wndo->xmax)
{
newx = wndo->xmax;
wndo->deltax = -wndo->deltax;
hit = true;
}
wndo->xpos = newx;
/* Update Y position */
newy = wndo->ypos + wndo->deltay;
/* Check for collision with top or bottom side */
if (newy <= 0)
{
newy = 0;
wndo->deltay = -wndo->deltay;
hit = true;
}
else if (newy >= wndo->ymax)
{
newy = wndo->ymax;
wndo->deltay = -wndo->deltay;
hit = true;
}
wndo->ypos = newy;
/* Set the new window position */
pos.x = b32toi(newx);
pos.y = b32toi(newy);
ret = nxtk_setposition(wndo->hwnd, &pos);
if (ret < 0)
{
printf("pwfb_move_window: ERROR:"
"nxtk_setposition failed: %d\n",
errno);
return false;
}
/* If we hit an edge, the raise the window */
if (hit)
{
ret = nxtk_raise(wndo->hwnd);
if (ret < 0)
{
printf("pwfb_move_window: ERROR:"
"nxtk_raise failed: %d\n",
errno);
return false;
}
}
return true;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwfb_motion
****************************************************************************/
bool pwfb_motion(FAR struct pwfb_state_s *st)
{
int wndx;
/* Move each window */
for (wndx = 0; wndx < 3; wndx++)
{
if (!pwfb_move_window(st, wndx))
{
printf("pwfb_motion: ERROR:"
"pwfb_move_window failed for window %d\n",
wndx + 1);
}
}
return true;
}