From e5c56aaab675ace859b8eb5defe5f5ccd573b65e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 7 Apr 2019 16:04:21 -0600 Subject: [PATCH] graphics: A little more progress with software cursors. --- graphics/Kconfig | 2 +- graphics/nxbe/nxbe.h | 28 +++-- graphics/nxbe/nxbe_cursor.c | 211 ++++++++++++++++++++++++++++++++++- include/nuttx/video/cursor.h | 1 - libs/libnx/nxmu/nx_cursor.c | 1 - 5 files changed, 229 insertions(+), 14 deletions(-) diff --git a/graphics/Kconfig b/graphics/Kconfig index c763bb10b2..418a3d8d1c 100644 --- a/graphics/Kconfig +++ b/graphics/Kconfig @@ -77,7 +77,7 @@ config NX_NOCURSOR config NX_SWCURSOR bool "Software cursor support" - depends on NX_RAMBACKED && EXPERIMENTAL + depends on NX_RAMBACKED && !NX_LCDDRIVER && EXPERIMENTAL config NX_HWCURSOR bool "Software cursor support" diff --git a/graphics/nxbe/nxbe.h b/graphics/nxbe/nxbe.h index 781b0d49d0..3035d81e47 100644 --- a/graphics/nxbe/nxbe.h +++ b/graphics/nxbe/nxbe.h @@ -182,6 +182,24 @@ struct nxbe_clipops_s FAR const struct nxgl_rect_s *rect); }; +/* Cursor *******************************************************************/ + +#if defined(CONFIG_NX_SWCURSOR) +struct nxbe_cursor_s +{ + bool visible; /* True: the cursor is visible */ + struct nxgl_rect_s bounds; /* Cursor image bounding box */ + FAR uint8_t *cimage; /* Cursor image at 2-bits/pixel */ + FAR nxgl_mxpixel_t *backgd; /* Cursor background in device pixels */ +}; +#elif defined(CONFIG_NX_HWCURSOR) +struct nxbe_cursor_s +{ + bool visible; /* True: the cursor is visible */ + struct cursor_pos_s pos; /* The current cursor position */ +}; +#endif + /* Back-end state ***********************************************************/ /* This structure describes the overall back-end window state */ @@ -193,15 +211,7 @@ struct nxbe_state_s #if defined(CONFIG_NX_SWCURSOR) || defined(CONFIG_NX_HWCURSOR) /* Cursor support */ - struct - { - bool visible; /* True: the cursor is visible */ - struct cursor_pos_s pos; /* The current cursor position */ -#ifdef CONFIG_NX_SWCURSOR - FAR struct cursor_image_s image; /* Cursor image */ - FAR nxgl_mxpixel_t *bkgd; /* Cursor background */ -#endif - } cursor; + struct nxbe_cursor_s cursor; /* Cursor support */ #endif /* The window list (with the background window always at the bottom) */ diff --git a/graphics/nxbe/nxbe_cursor.c b/graphics/nxbe/nxbe_cursor.c index a5a4e35452..b8d590423b 100644 --- a/graphics/nxbe/nxbe_cursor.c +++ b/graphics/nxbe/nxbe_cursor.c @@ -41,13 +41,186 @@ #include +#include "nxglib_bitblit.h" #include "nxbe.h" +#if defined(CONFIG_NX_SWCURSOR) || defined(CONFIG_NX_HWCURSOR) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxbe_map_color + * + * Description: + * Map a 2-bit cursor pixel value to a device pixel value + * + * Input Parameters: + * be - The back-end state structure instance + * pixel - Pixel to be mapped + * + * Returned Value: + * The mapped pixel. + * + ****************************************************************************/ + +static nxgl_mxcolor_t nxbe_map_color(FAR struct nxbe_state_s *be, int plane, + uint8_t pixel) +{ + switch pixel + { + case 0: + default: + return 0; /* Should not happen */ + + case 1: + return be->cursor.color1[plane]; + break; + + case 2: + return be->cursor.color2[plane]; + break; + + case 3: + return be->cursor.color3[plane]; + break; + } +} + +/**************************************************************************** + * Name: nxbe_cursor_update + * + * Description: + * Update the cursor region + * + * Input Parameters: + * be - The back-end state structure instance + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void nxbe_cursor_update(FAR struct nxbe_state_s *be, int plane) +{ + struct nxgl_rect_s intersection; + FAR struct nxbe_plane_s *plane; + FAR unsigned int *sstride; + FAR unsigned int *dstride; + FAR uint8_t *fbmem; + FAR uint8_t *src; + FAR uint8_t *sline; + FAR NXGL_PIXEL_T *dest; + FAR uint8_t *dline; + nxgl_coord_t width; + nxgl_coord_t height; + int row; + int col; + + /* Handle the case some or all of the cursor image is off of the display. */ + + nxgl_rectintersect(&intersction, &be->cursor.bounds, &be->backgd.bounds); + if (!nxgl_nullrect(&intersection)) + { + /* Get the width and the height of the images in pixels/rows */ + + width = be->cursor.bounds.pt2.x = be->cursor.bounds.pt1.x + 1; + height = be->cursor.bounds.pt2.y = be->cursor.bounds.pt1.xy + 1; + + /* Get the width of the images in bytes. */ + + sstride = (width + 3) >> 2; /* 2 bits per pixel, 4 pixels per byte */ + + plane = &wnd->be->plane[0]; + dstride = plane->pinfo.stride; + + /* Erase the old cursor position */ +#warning Missing logic + + /* Update any cursor graphics on top of the device display to include + * the modified cursor. + * + * REVISIT: This will only work for a single plane and for bits per pixel + * greater than or equal to 8. + */ + + fbmem = (FAR uint8_t *)plane->pinfo.fbmem; + sline = be->cursor.image; + dline = (FAR uint8_t *)fbmem + dstride * be->cursor.bounds.pt1.y + + NXGL_SCALEX(be->cursor.bounds.pt1.x); + + for (row = 0; row < height; row++) + { + src = sline; + dest = (FAR NXGL_PIXEL_T *)dline; + + for (col = 0; col < width; ) + { + /* Data is always packed MS first */ + + uint8_t spixel = (*src & >> 6) & 3 + if (pixel != 0) + { + *dest = nxbe_map_color(be, 0, spixel); + } + + col++; + dest++; + + if (col < width) + { + spixel = (*src & >> 4) & 3 + if (pixel != 0) + { + *dest = nxbe_map_color(be, 0, spixel); + } + } + + col++; + dest++; + + if (col < width) + { + spixel = (*src & >> 2) & 3 + if (pixel != 0) + { + *dest = nxbe_map_color(be, 0, spixel); + } + } + + col++; + dest++; + + if (col < width) + { + spixel = *src & 3 + if (pixel != 0) + { + *dest = nxbe_map_color(be, 0, spixel); + } + } + + col++; + dest++; + + /* Update source column addresses */ + + src++; + } + + /* Update the row addresses */ + + sline += sstride; + dline += dstride; + } + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ -#if defined(CONFIG_NX_SWCURSOR) || defined(CONFIG_NX_HWCURSOR) /**************************************************************************** * Name: nxbe_cursor_enable * @@ -65,7 +238,41 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable) { -#warning Missing logic + /* Are we enabling the cursor */ + + if (enable && !be->cursor.visible) + { + /* Mark the cursor visible */ + + be->cursor.visible = true; + } + + /* Are we disabling the cursor ? */ + + else if (!enable && be->cursor.visible) + { + /* Mark the cursor not visible */ + + be->cursor.visible = false; + } + else + { + /* No change in state.. do nothing */ + + return; + } + +#ifdef CONFIG_NX_SWCURSOR + /* For the software cursor, we need to update the cursor region */ + + nxbe_cursor_update(be); +#else + /* For a hardware cursor, this would require some interaction with the + * grahics device. + */ + +# error Missing logic +#endif } /**************************************************************************** diff --git a/include/nuttx/video/cursor.h b/include/nuttx/video/cursor.h index a2f04d7c4f..bc54df0471 100644 --- a/include/nuttx/video/cursor.h +++ b/include/nuttx/video/cursor.h @@ -90,7 +90,6 @@ struct cursor_image_s { cursor_coord_t width; /* Width of the cursor image in pixels */ cursor_coord_t height; /* Height of the cursor image in pixels */ - cursor_coord_t stride; /* Width of the image in bytes */ cursor_color_t color1; /* Color1 is main color of the cursor */ cursor_color_t color2; /* Color2 is color of any border */ cursor_color_t color3; /* Color3 is the blended color */ diff --git a/libs/libnx/nxmu/nx_cursor.c b/libs/libnx/nxmu/nx_cursor.c index 40a0f742da..ca9c57ec47 100644 --- a/libs/libnx/nxmu/nx_cursor.c +++ b/libs/libnx/nxmu/nx_cursor.c @@ -129,7 +129,6 @@ int nxcursor_setimage(NXHANDLE hnd, FAR struct cursor_image_s *image) outmsg.msgid = NX_SVRMSG_CURSOR_IMAGE; outmsg.image.width = image->width; outmsg.image.height = image->height; - outmsg.image.stride = image->stride; outmsg.image.color1 = image->color1; outmsg.image.color2 = image->color2; outmsg.image.color3 = image->color3;