apps/examples/pwfb: Extend example to verify software cursors. Untested on initial commit.

This commit is contained in:
Gregory Nutt 2019-04-10 09:24:08 -06:00
parent 0ff0a97ae4
commit 99382df286
5 changed files with 301 additions and 4 deletions

View File

@ -35,7 +35,10 @@
-include $(TOPDIR)/Make.defs
# NuttX NX Graphics Example.
# NuttX per-window frame buffer graphics example.
NXGLYPHS = $(APPDIR)$(DELIM)graphics$(DELIM)nxglyphs
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" "$(NXGLYPHS)$(DELIM)include"}
ASRCS =
CSRCS = pwfb_events.c pwfb_motion.c
@ -44,7 +47,7 @@ MAINSRC = pwfb_main.c
CONFIG_EXAMPLES_PWFB_PROGNAME ?= pwfb$(EXEEXT)
PROGNAME = $(CONFIG_EXAMPLES_PWFB_PROGNAME)
# NX built-in application info
# Per-Window frame buffer built-in application info
CONFIG_EXAMPLES_PWFB_CLIENT_PRIO ?= SCHED_PRIORITY_DEFAULT
CONFIG_EXAMPLES_PWFB_CLIENT_STACKSIZE ?= 2048

View File

@ -148,6 +148,20 @@
# endif
#endif
/* Cursor timing */
#if CONFIG_EXAMPLES_PWFB_RATECONTROL > 0
# define CURSOR_MOVING_DELAY (3000 / CONFIG_EXAMPLES_PWFB_RATECONTROL)
# define CURSOR_STATIONARY_DELAY (2000 / CONFIG_EXAMPLES_PWFB_RATECONTROL)
# define CURSOR_BLINKING_DELAY (5000 / CONFIG_EXAMPLES_PWFB_RATECONTROL)
# define CURSOR_BLINK_DELAY ( 500 / CONFIG_EXAMPLES_PWFB_RATECONTROL)
#else
# define CURSOR_MOVING_DELAY (0)
# define CURSOR_STATIONARY_DELAY (0)
# define CURSOR_BLINKING_DELAY (0)
# define CURSOR_BLINK_DELAY (0)
#endif
/****************************************************************************
* Public Types
****************************************************************************/
@ -167,6 +181,37 @@ struct pwfb_window_s
b16_t deltay; /* Current Y speed */
};
#ifdef CONFIG_NX_SWCURSOR
/* We will run the cursor in 3 different states:
*
* 1. Moving
* 2. Stationary
* 3. Enabling/disabling
*/
enum pfwb_cursor_state_s
{
PFWB_CURSOR_MOVING = 0,
PFWB_CURSOR_STATIONARY,
PFWB_CURSOR_BLINKING
};
/* Describes the unique state of the cursor */
struct pwfb_cursor_s
{
enum pfwb_cursor_state_s state; /* Current cursor state */
bool visible; /* True: The cursor is visible */
int countdown; /* Countdown until next state */
int blinktime; /* Time remaining enabled/disabled */
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 */
};
#endif
/* Describes the overall state of the example */
struct pwfb_state_s
@ -197,6 +242,12 @@ struct pwfb_state_s
uint8_t fwidth; /* Max width of a font in pixels */
uint8_t spwidth; /* The width of a space */
#ifdef CONFIG_NX_SWCURSOR
/* Cursor-specific state */
struct pwfb_cursor_s cursor;
#endif
/* Window-specific state */
struct pwfb_window_s wndo[3];

View File

@ -62,6 +62,12 @@
#include <nuttx/nx/nxbe.h>
#include <nuttx/nx/nxfonts.h>
#ifdef CONFIG_NX_SWCURSOR
# undef CONFIG_NXWIDGETS_BPP
# define CONFIG_NXWIDGETS_BPP CONFIG_EXAMPLES_PWFB_BPP
# include "cursor-arrow1-30x30.h"
#endif
#include "pwfb_internal.h"
/****************************************************************************
@ -492,6 +498,64 @@ errout_with_hwnd:
return false;
}
/****************************************************************************
* Name: pwfb_configure_cursor
****************************************************************************/
#ifdef CONFIG_NX_SWCURSOR
static bool pwfb_configure_cursor(FAR struct pwfb_state_s *st,
FAR struct nxgl_point_s *pos,
double deltax, double deltay)
{
int ret;
/* Initialize the data structure */
st->cursor.state = PFWB_CURSOR_MOVING;
st->cursor.countdown = CURSOR_MOVING_DELAY;
st->cursor.blinktime = 0;
st->cursor.xpos = pos->x;
st->cursor.ypos = pos->y;
st->cursor.deltax = deltax;
st->cursor.deltay = deltay;
/* Set the cursor image */
ret = nxcursor_setimage(st->hnx, &g_arrow1Cursor);
if (ret < 0)
{
printf("pwfb_configure_cursor: ERROR: "
"nxcursor_setimage failed: %d\n",
errno);
return false;
}
/* Set the cursor position */
ret = nxcursor_setposition(st->hnx, pos);
if (ret < 0)
{
printf("pwfb_configure_cursor: ERROR: "
"nxcursor_setposition failed: %d\n",
errno);
return false;
}
/* Enable the cursor */
ret = nxcursor_enable(st->hnx, false);
if (ret < 0)
{
printf("pwfb_configure_cursor: ERROR: "
"nxcursor_enable failed: %d\n",
errno);
return false;
}
return true;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -655,6 +719,20 @@ int pwfb_main(int argc, char *argv[])
goto errout_with_hwnd3;
}
#ifdef CONFIG_NX_SWCURSOR
/* Configure the software cursor */
pos.x = wstate.xres / 2;
pos.x = wstate.yres / 2;
if (!pwfb_configure_cursor(&wstate, &pos, 2.900, -5.253))
{
printf("pwfb_main: ERROR: "
"pwfb_configure_cursor failed for window 2\n");
goto errout_with_hwnd3;
}
#endif
/* Now loop animating the windows */
for (; ; )
@ -664,12 +742,19 @@ int pwfb_main(int argc, char *argv[])
{
printf("pwfb_main: ERROR:"
"pwfb_motion failed\n");
goto errout_with_hwnd3;
goto errout_with_cursor;
}
}
errcode = EXIT_SUCCESS;
errout_with_cursor:
#ifdef CONFIG_NX_SWCURSOR
/* Disable the cursor */
(void)nxcursor_enable(wstate.hnx, false);
#endif
/* Close window 3 */
errout_with_hwnd3:

View File

@ -44,6 +44,7 @@
#include <errno.h>
#include <nuttx/nx/nxglib.h>
#include <nuttx/nx/nxcursor.h>
#include <nuttx/nx/nxtk.h>
#include "pwfb_internal.h"
@ -174,6 +175,155 @@ static inline bool pwfb_move_window(FAR struct pwfb_state_s *st, int wndx)
return true;
}
/****************************************************************************
* Name: pwfb_move_cursor
****************************************************************************/
#ifdef CONFIG_NX_SWCURSOR
static inline bool pwfb_move_cursor(FAR struct pwfb_state_s *st)
{
FAR struct nxgl_point_s pos;
b16_t newx;
b16_t newy;
int ret;
#ifdef CONFIG_EXAMPLES_PWFB_VERBOSE
printf("pwfb_move_cursor: State: %u countdown: %u blinktime: %u\n",
(unsigned int)st->cursor.state, (unsigned int)st->cursor.countdown,
(unsigned int)st->cursor.blinktime;
printf("pwfb_move_cursor: Velocity: (%lx.%04lx,%lx.%04lx)\n",
(unsigned long)st->cursor.deltax >> 16,
(unsigned long)st->cursor.deltax & 0xffff,
(unsigned long)st->cursor.deltay >> 16,
(unsigned long)st->cursor.deltay & 0xffff);
#endif
/* Handle the update based on cursor state */
/* If the state is not PFWB_CURSOR_STATIONARY, then update the cursor
* position.
*/
if (st->cursor.state != PFWB_CURSOR_STATIONARY)
{
/* Update X position */
newx = st->cursor.xpos + st->cursor.deltax;
/* Check for collision with left or right side */
if (newx <= 0)
{
newx = 0;
st->cursor.deltax = -st->cursor.deltax;
}
else if (newx >= st->cursor.xmax)
{
newx = st->cursor.xmax;
st->cursor.deltax = -st->cursor.deltax;
}
/* Update Y position */
newy = st->cursor.ypos + st->cursor.deltay;
/* Check for collision with top or bottom side */
if (newy <= 0)
{
newy = 0;
st->cursor.deltay = -st->cursor.deltay;
}
else if (newy >= st->cursor.ymax)
{
newy = st->cursor.ymax;
st->cursor.deltay = -st->cursor.deltay;
}
#ifdef CONFIG_EXAMPLES_PWFB_VERBOSE
printf("pwfb_move_cursor: Old pos: (%lx.%04lx,%lx.%04lx) "
"New pos: (%lx.%04lx,%lx.%04lx)\n",
(unsigned long)st->cursor.xpos >> 16,
(unsigned long)st->cursor.xpos & 0xffff,
(unsigned long)st->cursor.ypos >> 16,
(unsigned long)st->cursor.ypos & 0xffff,
(unsigned long)newx >> 16,
(unsigned long)newx & 0xffff,
(unsigned long)newy >> 16,
(unsigned long)newy & 0xffff);
#endif
/* Set the new cursor position */
st->cursor.xpos = newx;
st->cursor.ypos = newy;
pos.x = b16toi(newx);
pos.y = b16toi(newy);
printf("pwfb_move_cursor: Set position (%d,%d)\n", pos.x, pos.y);
ret = nxcursor_setposition(st->hnx, &pos);
if (ret < 0)
{
printf("nxcursor_setposition: ERROR:"
"nxcursor_setposition failed: %d\n",
errno);
return false;
}
}
/* Check for state changes */
switch (st->cursor.state)
{
case PFWB_CURSOR_MOVING:
if (--st->cursor.countdown <= 0)
{
/* Set up for the the STATIONARY state next */
st->cursor.state = PFWB_CURSOR_STATIONARY;
st->cursor.countdown = CURSOR_STATIONARY_DELAY;
}
break;
case PFWB_CURSOR_STATIONARY:
if (--st->cursor.countdown <= 0)
{
/* Set up for the the BLINKING state next */
st->cursor.state = PFWB_CURSOR_BLINKING;
st->cursor.countdown = CURSOR_BLINKING_DELAY;
st->cursor.blinktime = CURSOR_BLINK_DELAY;
}
break;
case PFWB_CURSOR_BLINKING:
if (--st->cursor.countdown <= 0)
{
/* Set up for the the MOVING state next */
st->cursor.state = PFWB_CURSOR_MOVING;
st->cursor.countdown = CURSOR_MOVING_DELAY;
st->cursor.visible = true;
nxcursor_enable(st->hnx, true);
}
else if (--st->cursor.blinktime <= 0)
{
/* Toggle visibility */
st->cursor.blinktime = CURSOR_BLINK_DELAY;
st->cursor.visible = !st->cursor.visible;
nxcursor_enable(st->hnx, st->cursor.visible);
}
}
return true;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -198,5 +348,14 @@ bool pwfb_motion(FAR struct pwfb_state_s *st)
}
}
#ifdef CONFIG_NX_SWCURSOR
/* Move the cursor */
if (!pwfb_move_cursor(st))
{
printf("pwfb_motion: ERROR: pwfb_move_cursor failed\n");
}
#endif
return true;
}

View File

@ -386,4 +386,3 @@ namespace NXWidgets
#endif // __cplusplus
#endif // __APPS_INCLUDE_GRAPHICS_NXWIDGETS_CNXTKWINDOW_HXX