This commit adds apps/examples/pwlines, another test of the pw-window framebuffer lgoic.

Squashed commit of the following:

    apps/examples/pwlines:  The example is complete and verified.

    apps/examples/pwlines:  A little more progress between distractions.

    apps/examples/pwlines:  Beginning of another per-window framebuffer test/examples.
This commit is contained in:
Gregory Nutt 2019-03-20 12:36:46 -06:00
parent 1a6c6e2eb4
commit e26d78f40a
11 changed files with 1683 additions and 10 deletions

View File

@ -4,7 +4,7 @@
#
config EXAMPLES_PWFB
tristate "NX Per-Window Framebuffer Example"
tristate "NX Per-Window Framebuffer Text Example"
default n
depends on NX
select LIB_BOARDCTL

View File

@ -205,7 +205,7 @@ static bool pwfb_state_initialize(FAR struct pwfb_state_s *st)
st->wndo[2].color[0] = CONFIG_EXAMPLES_PWFB_COLOR3;
st->color[0] = CONFIG_EXAMPLES_PWFB_TBCOLOR;
/* Connect each widnow to the font cache. They cannot share the
/* Connect each window to the font cache. They cannot share the
* font cache becuse of the differing background colors.
*/
@ -407,6 +407,13 @@ static bool pwfb_configure_window(FAR struct pwfb_state_s *st, int wndx,
printf("nxeq_opentoolbar: nxtk_opentoolbar failed: %d\n", errno);
}
/* There is a race condition here we resolve by making the main thread
* lowest in priority. In order for the size and position to take effect,
* a command is sent to server which responds with an event. So we need
* to be synchronized at this point or the following fill will fail because
* it depends on current knowlede of the size and position.
*/
/* 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.
@ -441,13 +448,6 @@ static bool pwfb_configure_window(FAR struct pwfb_state_s *st, int wndx,
goto errout_with_hwnd;
}
/* There is a race condition here we resolve by making the main thread
* lowest in priority. In order for the size and position to take effect,
* a command is sent to server which responds with an event. So we need
* to be synchronized at this point or the following fill will fail because
* it depends on current knowlede of the size and position.
*/
/* Add the text to the display, character at a time */
textpos.x = st->spwidth;
@ -592,7 +592,7 @@ int pwfb_main(int argc, char *argv[])
{
printf("pwfb_main: ERROR: "
"pwfb_configure_window failed for window 1\n");
goto errout_with_fontcache;
goto errout_with_hwnd1;
}
/* Open window 2 */

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

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

138
examples/pwlines/Kconfig Normal file
View File

@ -0,0 +1,138 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_PWLINES
tristate "NX Per-Window Framebuffer Graphics Example"
default n
depends on NX
select LIB_BOARDCTL
select NX_RAMBACKED
---help---
Enable the NX per-window framebuffer example
if EXAMPLES_PWLINES
config EXAMPLES_PWLINES_DEFAULT_COLORS
bool "Use Default Colors"
default y
if !EXAMPLES_PWLINES_DEFAULT_COLORS
config EXAMPLES_PWLINES_BGCOLOR
hex "Background Color"
---help---
The color of the background. Default depends on config EXAMPLES_PWLINES_BPP.
config EXAMPLES_PWLINES_COLOR1
hex "Color of Window 1"
---help---
The color of window 1. Default depends on config EXAMPLES_PWLINES_BPP.
config EXAMPLES_PWLINES_COLOR2
hex "Color of Window 2"
---help---
The color of window 2. Default depends on config EXAMPLES_PWLINES_BPP.
config EXAMPLES_PWLINES_COLOR3
hex "Color of Window 3"
---help---
The color of window 3. Default depends on config EXAMPLES_PWLINES_BPP.
config EXAMPLES_PWLINES_BORDERCOLOR
hex "Circle border Color"
---help---
The color of the circular border drawn in the window. Default depends
on EXAMPLES_PWLINES_BPP.
config EXAMPLES_PWLINES_FACECOLOR
hex "Circle face Color"
---help---
The color of the circular region filled in the window. Default depends
on EXAMPLES_PWLINES_BPP.
config EXAMPLES_PWLINES_LINECOLOR
hex "Line Color"
---help---
The color of the central lines drawn in the window. Default depends
on EXAMPLES_PWLINES_BPP.
endif
config EXAMPLES_PWLINES_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.
config EXAMPLES_PWLINES_LINEWIDTH
int "Line Width"
default 8
---help---
Selects the width of the lines in pixels (default: 16)
config EXAMPLES_PWLINES_BORDERWIDTH
int "Border Width"
default 8
---help---
The width of the circular border drawn in the background window. (default: 16).
config EXAMPLES_PWLINES_RATECONTROL
int "Frame rate control"
default 100
range 0 1000
---help---
This is the inter-frame period in milliseconds that is used to
control the framerate. A value of zero will disable frame controls
and the rendering will occur as fast as is possible.
If you run this example with high frame rates, it becomes unstable.
This is probably a bug in the example: It may not be accounting
for for some asynchronous behaviors.
config EXAMPLES_PWLINES_VERBOSE
bool "Verbose output"
default n
comment "Tasking options"
config EXAMPLES_PWLINES_PROGNAME
string "Program name"
default "pwlines"
depends on BUILD_LOADABLE
---help---
This is the name of the program that will be use when the NSH ELF
program is installed.
config EXAMPLES_PWLINES_CLIENT_STACKSIZE
int "Example Main Stack Size"
default 2048
---help---
The stacksize to use when starting the example main().
Default 2048
config EXAMPLES_PWLINES_CLIENT_PRIO
int "Client Priority"
default 90
---help---
The priority to use when staring the example main(). This priority
should be lower than both the listener and server priorities (See
CONFIG_NXSTART_SERVERPRIO). Default: 90
config EXAMPLES_PWLINES_LISTENER_STACKSIZE
int "Listener Stack Size"
default 2048
---help---
The stacksize to use when creating the NX server. Default 2048
config EXAMPLES_PWLINES_LISTENER_PRIO
int "Listener Priority"
default 100
---help---
The priority of the event listener thread. This priority should be
above the client priority but below the server priority (See
CONFIG_NXSTART_SERVERPRIO). Default 100.
endif

View File

@ -0,0 +1,39 @@
############################################################################
# apps/examples/pwlines/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_PWLINES),)
CONFIGURED_APPS += examples/pwlines
endif

58
examples/pwlines/Makefile Normal file
View File

@ -0,0 +1,58 @@
############################################################################
# apps/examples/pwlines/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 = pwlines_events.c pwlines_motion.c pwlines_update.c
MAINSRC = pwlines_main.c
CONFIG_EXAMPLES_PWLINES_PROGNAME ?= pwlines$(EXEEXT)
PROGNAME = $(CONFIG_EXAMPLES_PWLINES_PROGNAME)
# NX built-in application info
CONFIG_EXAMPLES_PWLINES_CLIENT_PRIO ?= SCHED_PRIORITY_DEFAULT
CONFIG_EXAMPLES_PWLINES_CLIENT_STACKSIZE ?= 2048
APPNAME = pwlines
PRIORITY = $(CONFIG_EXAMPLES_PWLINES_CLIENT_PRIO)
STACKSIZE = $(CONFIG_EXAMPLES_PWLINES_CLIENT_STACKSIZE)
MODULE = CONFIG_EXAMPLES_PWLINES
include $(APPDIR)/Application.mk

View File

@ -0,0 +1,187 @@
/****************************************************************************
* examples/pwlines/pwlines_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 "pwlines_internal.h"
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static void pwlines_wndo_redraw(NXTKWINDOW hwnd,
FAR const struct nxgl_rect_s *rect, bool morem, FAR void *arg);
static void pwlines_wndo_position(NXTKWINDOW hwnd, FAR
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_pwlines_wncb =
{
pwlines_wndo_redraw, /* redraw */
pwlines_wndo_position /* position */
#ifdef CONFIG_NX_XYINPUT
, NULL /* mousein */
#endif
#ifdef CONFIG_NX_KBD
, NULL /* kbdin */
#endif
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_wndo_redraw
****************************************************************************/
static void pwlines_wndo_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("pwlines_wndo_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: pwlines_wndo_position
****************************************************************************/
static void pwlines_wndo_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 pwlines_state_s *st = (FAR struct pwlines_state_s *)arg;
#ifdef CONFIG_EXAMPLES_PWLINES_VERBOSE
/* Report the position */
printf("pwlines_wndo_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);
#endif
/* 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("pwlines_wndo_position: Have xres=%d yres=%d\n",
st->xres, st->yres);
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_listener
****************************************************************************/
FAR void *pwlines_listener(FAR void *arg)
{
FAR struct pwlines_state_s *st = (FAR struct pwlines_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("pwlines_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("pwlines_listener: Connected\n");
}
}
}

View File

@ -0,0 +1,246 @@
/****************************************************************************
* examples/pwlines/pwlines_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_PWLINES_PWLINES_INTERNAL_H
#define __EXAMPLES_PWLINES_PWLINES_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/video/rgbcolors.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
/* Task priorities */
#if CONFIG_EXAMPLES_PWLINES_CLIENT_PRIO >= CONFIG_EXAMPLES_PWLINES_LISTENER_PRIO || \
CONFIG_EXAMPLES_PWLINES_CLIENT_PRIO >= CONFIG_NXSTART_SERVERPRIO
# warning Client priority must be lower than both the listener and server priorities
#endif
#if CONFIG_EXAMPLES_PWLINES_LISTENER_PRIO >= CONFIG_NXSTART_SERVERPRIO
# warning Listener priority must be lower than the server priority
#endif
/* Default colors */
#ifndef CONFIG_EXAMPLES_PWLINES_BGCOLOR
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_BGCOLOR 0x007b68ee
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_BGCOLOR 0x7b5d
# else
# define CONFIG_EXAMPLES_PWLINES_BGCOLOR ' '
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_COLOR1
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_COLOR1 RGB24_DARKGREEN
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_COLOR1 RGB16_DARKGREEN
# else
# define CONFIG_EXAMPLES_PWLINES_COLOR1 RGB8_DARKGREEN
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_COLOR2
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_COLOR2 RGB24_GREEN
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_COLOR2 RGB16_GREEN
# else
# define CONFIG_EXAMPLES_PWLINES_COLOR2 RGB8_GREEN
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_COLOR3
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_COLOR3 RGB24_LIGHTGREEN
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_COLOR3 RGB16_LIGHTGREEN
# else
# define CONFIG_EXAMPLES_PWLINES_COLOR3 RGB8_LIGHTGREEN
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_BORDERWIDTH
# define CONFIG_EXAMPLES_PWLINES_BORDERWIDTH 16
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_BORDERCOLOR
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_BORDERCOLOR RGB24_YELLOW
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_BORDERCOLOR RGB16_YELLOW
# else
# define CONFIG_EXAMPLES_PWLINES_BORDERCOLOR RGB8_YELLOW
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_FACECOLOR
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_FACECOLOR RGB24_BEIGE
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_FACECOLOR RGB16_BEIGE
# else
# define CONFIG_EXAMPLES_PWLINES_FACECOLOR RGB8_BEIGE
# endif
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_LINEWIDTH
# define CONFIG_EXAMPLES_PWLINES_LINEWIDTH 16
#endif
#ifndef CONFIG_EXAMPLES_PWLINES_LINECOLOR
# if CONFIG_EXAMPLES_PWLINES_BPP == 24 || CONFIG_EXAMPLES_PWLINES_BPP == 32
# define CONFIG_EXAMPLES_PWLINES_LINECOLOR RGB24_GOLD
# elif CONFIG_EXAMPLES_PWLINES_BPP == 16
# define CONFIG_EXAMPLES_PWLINES_LINECOLOR RGB16_GOLD
# else
# define CONFIG_EXAMPLES_PWLINES_LINECOLOR RGB8_GOLD
# endif
#endif
/* Helpers */
#ifndef MIN
# define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
# define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* Describes the unique state of one window */
struct pwlines_window_s
{
NXTKWINDOW hwnd; /* Window handle */
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]; /* Window color */
struct nxgl_size_s size; /* Drawable window size */
struct nxgl_point_s center; /* Circle center position */
struct nxgl_vector_s previous; /* Previous line vector */
nxgl_coord_t radius; /* Internal, drawable radius */
b16_t angle; /* Current line angle */
b16_t xmax; /* Max X position */
b16_t ymax; /* Max Y position */
b16_t xpos; /* Current X position */
b16_t ypos; /* Current Y position */
b16_t deltax; /* Current X speed */
b16_t deltay; /* Current Y speed */
};
/* Describes the overall state of the example */
struct pwlines_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 */
/* Graphics hardware */
nxgl_coord_t xres; /* Horizontal resolution */
nxgl_coord_t yres; /* Vertical resolution */
/* Image properties */
nxgl_mxpixel_t facecolor[CONFIG_NX_NPLANES]; /* Color of circle center region */
nxgl_mxpixel_t bordercolor[CONFIG_NX_NPLANES]; /* Color of circle border */
nxgl_mxpixel_t linecolor[CONFIG_NX_NPLANES]; /* Color of rotating line */
/* Window-specific state */
struct pwlines_window_s wndo[3];
};
/****************************************************************************
* Public Data
****************************************************************************/
/* NX callback vtables */
extern const struct nx_callback_s g_pwlines_wncb;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR void *pwlines_listener(FAR void *arg);
void pwlines_circle(FAR struct pwlines_state_s *st);
void pwlines_update(FAR struct pwlines_state_s *st);
bool pwlines_motion(FAR struct pwlines_state_s *st);
#endif /* __EXAMPLES_PWLINES_PWLINES_INTERNAL_H */

View File

@ -0,0 +1,536 @@
/****************************************************************************
* examples/pwlines/pwlines_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 "pwlines_internal.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_server_initialize
****************************************************************************/
static bool pwlines_server_initialize(FAR struct pwlines_state_s *st)
{
struct sched_param param;
int ret;
/* Set the client task priority */
param.sched_priority = CONFIG_EXAMPLES_PWLINES_CLIENT_PRIO;
ret = sched_setparam(0, &param);
if (ret < 0)
{
printf("pwlines_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("pwlines_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("pwlines_server_initialize: ERROR: "
"vnc_default_fbinitialize failed: %d\n",
ret);
nx_disconnect(st->hnx);
return false;
}
#endif
}
else
{
printf("pwlines_server_initialize: ERROR: "
"nx_connect failed: %d\n",
errno);
return false;
}
return true;
}
/****************************************************************************
* Name: pwlines_listener_initialize
****************************************************************************/
static bool pwlines_listener_initialize(FAR struct pwlines_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_PWLINES_LISTENER_PRIO;
(void)pthread_attr_setschedparam(&attr, &param);
(void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_PWLINES_LISTENER_STACKSIZE);
ret = pthread_create(&thread, &attr, pwlines_listener, st);
if (ret != 0)
{
printf("pwlines_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: pwlines_state_initialize
****************************************************************************/
static bool pwlines_state_initialize(FAR struct pwlines_state_s *st)
{
/* Initialize semaphores */
sem_init(&st->semevent, 0, 0);
/* Initialize color information (only a single color plane supported) */
st->wndo[0].color[0] = CONFIG_EXAMPLES_PWLINES_COLOR1;
st->wndo[1].color[0] = CONFIG_EXAMPLES_PWLINES_COLOR2;
st->wndo[2].color[0] = CONFIG_EXAMPLES_PWLINES_COLOR3;
st->facecolor[0] = CONFIG_EXAMPLES_PWLINES_FACECOLOR;
st->bordercolor[0] = CONFIG_EXAMPLES_PWLINES_BORDERCOLOR;
st->linecolor[0] = CONFIG_EXAMPLES_PWLINES_LINECOLOR;
return true;
}
/****************************************************************************
* Name: pwlines_configure_window
****************************************************************************/
static bool pwlines_configure_window(FAR struct pwlines_state_s *st, int wndx,
FAR struct nxgl_size_s *size,
FAR struct nxgl_point_s *pos,
double deltax, double deltay)
{
FAR struct pwlines_window_s *wndo = &st->wndo[wndx];
struct nxgl_rect_s rect;
int ret;
/* Set the total size of the window */
printf("pwlines_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("pwlines_configure_window: ERROR: "
"nxtk_setsize failed: %d\n", errno);
goto errout_with_hwnd;
}
/* Set the drawable size (excludes borders) */
wndo->size.h = size->h - 2 * CONFIG_NXTK_BORDERWIDTH;
wndo->size.w = size->w - 2 * CONFIG_NXTK_BORDERWIDTH;
/* Set the position of window */
printf("pwlines_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("pwlines_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.
*
* There is a race condition here we resolve by making the main thread
* lowest in priority. In order for the size and position to take effect,
* a command is sent to server which responds with an event. So we need
* to be synchronized at this point or the following fill will fail because
* it depends on current knowlede of the size and position.
*/
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("pwlines_configure_window: ERROR: "
"nxtk_fillwindow failed: %d\n",
errno);
goto errout_with_hwnd;
}
/* Set up for motion */
wndo->xmax = itob16(st->xres - size->w - 1);
wndo->ymax = itob16(st->yres - size->h - 1);
wndo->ypos = itob16(pos->y);
wndo->xpos = itob16(pos->x);
wndo->deltax = dtob16(deltax);
wndo->deltay = dtob16(deltay);
return true;
errout_with_hwnd:
printf("pwlines_configure_window: Close window %d\n", wndx + 1);
ret = nxtk_closewindow(wndo->hwnd);
if (ret < 0)
{
printf("pwlines_configure_window: ERROR: "
"nxtk_closewindow failed: %d\n",
errno);
}
return false;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_main
****************************************************************************/
#ifdef BUILD_MODULE
int main(int argc, FAR char *argv[])
#else
int pwlines_main(int argc, char *argv[])
#endif
{
struct pwlines_state_s wstate;
struct nxgl_size_s size;
struct nxgl_point_s pos;
nxgl_coord_t mindim;
nxgl_mxpixel_t color;
unsigned int elapsed;
int errcode = EXIT_SUCCESS;
int ret;
/* Connect to the NX server */
memset(&wstate, 0, sizeof(struct pwlines_state_s));
if (!pwlines_server_initialize(&wstate) || wstate.hnx == NULL)
{
printf("pwlines_main: ERROR: "
"Failed to get NX handle\n");
goto errout;
}
printf("pwlines_main: NX handle=%p\n", wstate.hnx);
/* Start the listener thread */
if (!pwlines_listener_initialize(&wstate))
{
printf("pwlines_main: ERROR: "
"pwlines_listener_initialize failed\n");
goto errout_with_nx;
}
/* Initialize the window state, colors, cache, etc. */
if (!pwlines_state_initialize(&wstate))
{
printf("pwlines_main: ERROR: "
"pwlines_state_initialize failed\n");
goto errout_with_nx;
}
/* Set the background to the configured background color */
printf("pwlines_main: Set background color=%d\n",
CONFIG_EXAMPLES_PWLINES_BGCOLOR);
color = CONFIG_EXAMPLES_PWLINES_BGCOLOR;
ret = nx_setbgcolor(wstate.hnx, &color);
if (ret < 0)
{
printf("pwlines_main: nx_setbgcolor failed: %d\n", errno);
goto errout_with_nx;
}
/* Open window 1 */
printf("pwlines_main: Open window 1\n");
wstate.wndo[0].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED,
&g_pwlines_wncb, (FAR void *)&wstate);
if (wstate.wndo[0].hwnd == NULL)
{
printf("pwlines_main: ERROR: "
"nxtk_openwindow failed: %d\n",
errno);
goto errout_with_nx;
}
printf("pwlines_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("pwlines_main: Screen resolution (%d,%d)\n",
wstate.xres, wstate.yres);
/* Configure window 1 */
mindim = MIN(wstate.xres, wstate.yres);
size.w = mindim / 2;
size.h = size.w;
pos.x = wstate.xres / 8;
pos.y = wstate.yres / 8;
if (!pwlines_configure_window(&wstate, 0, &size, &pos, 4.200, 4.285))
{
printf("pwlines_main: ERROR: "
"pwlines_configure_window failed for window 1\n");
goto errout_with_hwnd1;
}
/* Open window 2 */
printf("pwlines_main: Open window 2\n");
wstate.wndo[1].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED,
&g_pwlines_wncb, (FAR void *)&wstate);
if (wstate.wndo[1].hwnd == NULL)
{
printf("pwlines_main: ERROR: "
"nxtk_openwindow failed: %d\n",
errno);
goto errout_with_hwnd1;
}
printf("pwlines_main: hwnd1=%p\n", wstate.wndo[1].hwnd);
/* Configure window 2 (same size) */
pos.x = wstate.xres / 4;
pos.y = wstate.yres / 4;
if (!pwlines_configure_window(&wstate, 1, &size, &pos, -3.317, 5.0))
{
printf("pwlines_main: ERROR: "
"pwlines_configure_window failed for window 2\n");
goto errout_with_hwnd2;
}
/* Open window 3 */
printf("pwlines_main: Open window 3\n");
wstate.wndo[2].hwnd = nxtk_openwindow(wstate.hnx, NXBE_WINDOW_RAMBACKED,
&g_pwlines_wncb, (FAR void *)&wstate);
if (wstate.wndo[2].hwnd == NULL)
{
printf("pwlines_main: ERROR: "
"nxtk_openwindow failed: %d\n",
errno);
goto errout_with_hwnd2;
}
printf("pwlines_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 (!pwlines_configure_window(&wstate, 2, &size, &pos, 4.600, -3.852))
{
printf("pwlines_main: ERROR: "
"pwlines_configure_window failed for window 2\n");
goto errout_with_hwnd3;
}
/* Apply the initial graphics */
pwlines_circle(&wstate);
pwlines_update(&wstate);
/* Now loop animating the windows */
elapsed = 0;
for (; ; )
{
usleep(CONFIG_EXAMPLES_PWLINES_RATECONTROL * 1000);
if (!pwlines_motion(&wstate))
{
printf("pwlines_main: ERROR:"
"pwlines_motion failed\n");
goto errout_with_hwnd3;
}
elapsed += CONFIG_EXAMPLES_PWLINES_RATECONTROL;
if (elapsed >= 1000)
{
pwlines_update(&wstate);
elapsed = 0;
}
}
errcode = EXIT_SUCCESS;
/* Close window 3 */
errout_with_hwnd3:
printf("pwlines_main: Close window #2\n");
ret = nxtk_closewindow(wstate.wndo[2].hwnd);
if (ret < 0)
{
printf("pwlines_main: ERROR: nxtk_closewindow failed: %d\n", errno);
}
/* Close window 2 */
errout_with_hwnd2:
printf("pwlines_main: Close window #2\n");
ret = nxtk_closewindow(wstate.wndo[1].hwnd);
if (ret < 0)
{
printf("pwlines_main: ERROR: nxtk_closewindow failed: %d\n", errno);
}
/* Close window1 */
errout_with_hwnd1:
printf("pwlines_main: Close window #1\n");
ret = nxtk_closewindow(wstate.wndo[0].hwnd);
if (ret < 0)
{
printf("pwlines_main: ERROR: nxtk_closewindow failed: %d\n", errno);
}
errout_with_nx:
/* Disconnect from the server */
printf("pwlines_main: Disconnect from the server\n");
nx_disconnect(wstate.hnx);
errout:
return errcode;
}

View File

@ -0,0 +1,202 @@
/****************************************************************************
* examples/pwlines/pwlines_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 "pwlines_internal.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_move_window
****************************************************************************/
static inline bool pwlines_move_window(FAR struct pwlines_state_s *st, int wndx)
{
FAR struct pwlines_window_s *wndo = &st->wndo[wndx];
FAR struct nxgl_point_s pos;
b16_t newx;
b16_t newy;
bool hit = false;
int ret;
#ifdef CONFIG_EXAMPLES_PWLINES_VERBOSE
printf("pwlines_move_window: Velocity: (%lx.%04lx,%lx.%04lx)\n",
(unsigned long)wndo->deltax >> 16,
(unsigned long)wndo->deltax & 0xffff,
(unsigned long)wndo->deltay >> 16,
(unsigned long)wndo->deltay & 0xffff);
printf("pwlines_move_window: Max: (%lx.%04lx,%lx.%04lx)\n",
(unsigned long)wndo->xmax >> 16,
(unsigned long)wndo->xmax & 0xffff,
(unsigned long)wndo->ymax >> 16,
(unsigned long)wndo->ymax & 0xffff);
#endif
/* 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;
}
/* 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;
}
#ifdef CONFIG_EXAMPLES_PWLINES_VERBOSE
printf("pwlines_move_window: Old pos: (%lx.%04lx,%lx.%04lx) "
"New pos: (%lx.%04lx,%lx.%04lx)\n",
(unsigned long)wndo->xpos >> 16,
(unsigned long)wndo->xpos & 0xffff,
(unsigned long)wndo->ypos >> 16,
(unsigned long)wndo->ypos & 0xffff,
(unsigned long)newx >> 16,
(unsigned long)newx & 0xffff,
(unsigned long)newy >> 16,
(unsigned long)newy & 0xffff);
#endif
/* Set the new window position */
wndo->xpos = newx;
wndo->ypos = newy;
pos.x = b16toi(newx);
pos.y = b16toi(newy);
printf("pwlines_move_window: Set position (%d,%d)\n", pos.x, pos.y);
ret = nxtk_setposition(wndo->hwnd, &pos);
if (ret < 0)
{
printf("pwlines_move_window: ERROR:"
"nxtk_setposition failed: %d\n",
errno);
return false;
}
/* If we hit an edge, the raise the window */
if (hit)
{
#ifdef CONFIG_EXAMPLES_PWLINES_VERBOSE
printf("pwlines_move_window: New velocity: (%lx.%04lx,%lx.%04lx)\n",
(unsigned long)wndo->deltax >> 16,
(unsigned long)wndo->deltax & 0xffff,
(unsigned long)wndo->deltay >> 16,
(unsigned long)wndo->deltay & 0xffff);
printf("pwlines_move_window: Raising window\n");
#endif
ret = nxtk_raise(wndo->hwnd);
if (ret < 0)
{
printf("pwlines_move_window: ERROR:"
"nxtk_raise failed: %d\n",
errno);
return false;
}
}
return true;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_motion
****************************************************************************/
bool pwlines_motion(FAR struct pwlines_state_s *st)
{
int wndx;
/* Move each window */
for (wndx = 0; wndx < 3; wndx++)
{
if (!pwlines_move_window(st, wndx))
{
printf("pwlines_motion: ERROR:"
"pwlines_move_window failed for window %d\n",
wndx + 1);
}
}
return true;
}

View File

@ -0,0 +1,256 @@
/****************************************************************************
* examples/pwlines/pwlines_update.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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <debug.h>
#include <fixedmath.h>
#include <nuttx/nx/nx.h>
#include <nuttx/nx/nxglib.h>
#include "pwlines_internal.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_NX_ANTIALIASING
/* If anti-aliasing is enabled, then we must clear a slightly
* larger region to prevent wierd edge effects.
*/
# define CLEAR_WIDTH (CONFIG_EXAMPLES_PWLINES_LINEWIDTH + 2)
#else
# define CLEAR_WIDTH CONFIG_EXAMPLES_PWLINES_LINEWIDTH
#endif
#ifndef MIN
# define MIN(a,b) (a < b ? a : b)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pwlines_circle
*
* Description:
* Draw a circle in each window.
*
****************************************************************************/
void pwlines_circle(FAR struct pwlines_state_s *st)
{
FAR struct pwlines_window_s *wndo;
nxgl_coord_t maxradius;
nxgl_coord_t radius;
int wndx;
int ret;
for (wndx = 0; wndx < 3; wndx++)
{
wndo = &st->wndo[wndx];
/* Get the maximum radius and center of the circle */
maxradius = MIN(wndo->size.h, wndo->size.h) >> 1;
wndo->center.x = wndo->size.w >> 1;
wndo->center.y = wndo->size.h >> 1;
/* Draw a circular background */
radius = maxradius - ((CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 1) / 2);
ret = nxtk_fillcirclewindow(wndo->hwnd, &wndo->center, radius,
st->facecolor);
if (ret < 0)
{
printf("pwlines_update: ERROR: nxtk_fillcirclewindow failed: %d\n",
ret);
}
/* Draw the circular border */
ret = nxtk_drawcirclewindow(wndo->hwnd, &wndo->center, radius,
CONFIG_EXAMPLES_PWLINES_BORDERWIDTH,
st->bordercolor);
if (ret < 0)
{
printf("pwlines_update: ERROR: nxtk_drawcirclewindow failed: %d\n",
ret);
}
/* Back off the radius to account for the thickness of border line
* and with a big fudge factor that will (hopefully) prevent the corners
* of the lines from overwriting the border. This is overly complicated
* here because we don't assume anything about the screen resolution or
* the borderwidth or the line thickness (and there are certainly some
* smarter ways to do this).
*/
if (maxradius > (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 80))
{
wndo->radius = maxradius - (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 40);
}
else if (maxradius > (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 60))
{
wndo->radius = maxradius - (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 30);
}
else if (maxradius > (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 40))
{
wndo->radius = maxradius - (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 20);
}
else if (maxradius > (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 20))
{
wndo->radius = maxradius - (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 10);
}
else if (maxradius > (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 10))
{
wndo->radius = maxradius - (CONFIG_EXAMPLES_PWLINES_BORDERWIDTH + 5);
}
else
{
wndo->radius = maxradius - CONFIG_EXAMPLES_PWLINES_BORDERWIDTH;
}
wndo->angle = 0;
wndo->previous.pt1.x = wndo->center.x;
wndo->previous.pt1.y = wndo->center.y;
wndo->previous.pt2.x = wndo->center.x;
wndo->previous.pt2.y = wndo->center.y;
}
}
/****************************************************************************
* Name: pwlines_update
*
* Description:
* Update line motion.
*
****************************************************************************/
void pwlines_update(FAR struct pwlines_state_s *st)
{
FAR struct pwlines_window_s *wndo;
struct nxgl_vector_s vector;
nxgl_coord_t halfx;
nxgl_coord_t halfy;
b16_t sinangle;
b16_t cosangle;
int wndx;
int ret;
/* Update each window */
for (wndx = 0; wndx < 3; wndx++)
{
wndo = &st->wndo[wndx];
/* Determine the position of the line on this pass */
sinangle = b16sin(wndo->angle);
halfx = b16toi(b16muli(sinangle, wndo->radius));
cosangle = b16cos(wndo->angle);
halfy = b16toi(b16muli(cosangle, wndo->radius));
vector.pt1.x = wndo->center.x + halfx;
vector.pt1.y = wndo->center.y + halfy;
vector.pt2.x = wndo->center.x - halfx;
vector.pt2.y = wndo->center.y - halfy;
printf("Angle: %08x vector: (%d,%d)->(%d,%d)\n",
wndo->angle, vector.pt1.x, vector.pt1.y, vector.pt2.x, vector.pt2.y);
/* Clear the previous line by overwriting it with the circle face color */
ret = nx_drawline(wndo->hwnd, &wndo->previous, CLEAR_WIDTH, st->facecolor,
NX_LINECAP_NONE);
if (ret < 0)
{
printf("pwlines_update: nx_drawline failed clearing: %d\n", ret);
}
/* Draw the new line */
ret = nx_drawline(wndo->hwnd, &vector,
CONFIG_EXAMPLES_PWLINES_LINEWIDTH, st->linecolor,
NX_LINECAP_NONE);
if (ret < 0)
{
printf("pwlines_update: nx_drawline failed clearing: %d\n", ret);
}
#ifdef CONFIG_NX_ANTIALIASING
/* If anti-aliasing is enabled, then we must clear a slightly
* larger region to prevent wierd edge effects.
*/
halfx = b16toi(b16muli(sinangle, wndo->radius + 1));
halfy = b16toi(b16muli(cosangle, wndo->radius + 1));
wndo->previous.pt1.x = wndo->center.x + halfx;
wndo->previous.pt1.y = wndo->center.y + halfy;
wndo->previous.pt2.x = wndo->center.x - halfx;
wndo->previous.pt2.y = wndo->center.y - halfy;
#else
memcpy(&wndo->previous, &vector, sizeof(struct nxgl_vector_s));
#endif
/* Set up for the next time through the loop. */
wndo->angle += b16PI / 16; /* 32 angular positions in full circle */
/* Check if we have gone all the way around */
if (wndo->angle > (31 * (2 * b16PI) / 32))
{
/* Wrap back to zero and continue with the test */
wndo->angle = 0;
}
}
}