diff --git a/graphics/Makefile b/graphics/Makefile index d70491f41bd..ef311c735ef 100644 --- a/graphics/Makefile +++ b/graphics/Makefile @@ -1,7 +1,8 @@ ############################################################################ # graphics/Makefile # -# Copyright (C) 2008-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved. +# Copyright (C) 2008-2009, 2011-2012, 2016, 2019 Gregory Nutt. All +# rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -87,24 +88,36 @@ gen8bppsource: ifeq ($(CONFIG_NX_RAMBACKED),y) $(Q) $(MAKE) -C nxglib -f Makefile.pwfb TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=8 EXTRADEFINES=$(EXTRADEFINES) endif +ifeq ($(CONFIG_NX_SWCURSOR),y) + $(Q) $(MAKE) -C nxglib -f Makefile.cursor TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=8 EXTRADEFINES=$(EXTRADEFINES) +endif gen16bppsource: $(Q) $(MAKE) -C nxglib -f Makefile.devblit TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=16 EXTRADEFINES=$(EXTRADEFINES) ifeq ($(CONFIG_NX_RAMBACKED),y) $(Q) $(MAKE) -C nxglib -f Makefile.pwfb TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=16 EXTRADEFINES=$(EXTRADEFINES) endif +ifeq ($(CONFIG_NX_SWCURSOR),y) + $(Q) $(MAKE) -C nxglib -f Makefile.cursor TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=16 EXTRADEFINES=$(EXTRADEFINES) +endif gen24bppsource: $(Q) $(MAKE) -C nxglib -f Makefile.devblit TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=24 EXTRADEFINES=$(EXTRADEFINES) ifeq ($(CONFIG_NX_RAMBACKED),y) $(Q) $(MAKE) -C nxglib -f Makefile.pwfb TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=24 EXTRADEFINES=$(EXTRADEFINES) endif +ifeq ($(CONFIG_NX_SWCURSOR),y) + $(Q) $(MAKE) -C nxglib -f Makefile.cursor TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=24 EXTRADEFINES=$(EXTRADEFINES) +endif gen32bppsources: $(Q) $(MAKE) -C nxglib -f Makefile.devblit TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=32 EXTRADEFINES=$(EXTRADEFINES) ifeq ($(CONFIG_NX_RAMBACKED),y) $(Q) $(MAKE) -C nxglib -f Makefile.pwfb TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=32 EXTRADEFINES=$(EXTRADEFINES) endif +ifeq ($(CONFIG_NX_SWCURSOR),y) + $(Q) $(MAKE) -C nxglib -f Makefile.cursor TOPDIR=$(TOPDIR) NXGLIB_BITSPERPIXEL=32 EXTRADEFINES=$(EXTRADEFINES) +endif gensources: gen1bppsources gen2bppsource gen4bppsource gen8bppsource gen16bppsource gen24bppsource gen32bppsources @@ -130,12 +143,14 @@ context: gensources clean: $(Q) $(MAKE) -C nxglib -f Makefile.devblit clean TOPDIR=$(TOPDIR) EXTRADEFINES=$(EXTRADEFINES) $(Q) $(MAKE) -C nxglib -f Makefile.pwfb clean TOPDIR=$(TOPDIR) EXTRADEFINES=$(EXTRADEFINES) + $(Q) $(MAKE) -C nxglib -f Makefile.cursor clean TOPDIR=$(TOPDIR) EXTRADEFINES=$(EXTRADEFINES) $(call DELFILE, $(BIN)) $(call CLEAN) distclean: clean $(Q) $(MAKE) -C nxglib -f Makefile.devblit distclean TOPDIR=$(TOPDIR) EXTRADEFINES=$(EXTRADEFINES) $(Q) $(MAKE) -C nxglib -f Makefile.pwfb distclean TOPDIR=$(TOPDIR) EXTRADEFINES=$(EXTRADEFINES) + $(Q) $(MAKE) -C nxglib -f Makefile.cursor distclean TOPDIR=$(TOPDIR) EXTRADEFINES=$(EXTRADEFINES) $(call DELFILE, Make.dep) $(call DELFILE, .depend) diff --git a/graphics/nxbe/nxbe.h b/graphics/nxbe/nxbe.h index b1c91df4a84..36529bcfd00 100644 --- a/graphics/nxbe/nxbe.h +++ b/graphics/nxbe/nxbe.h @@ -48,6 +48,7 @@ #include #include +#include #include /**************************************************************************** @@ -146,20 +147,40 @@ struct nxbe_pwfb_vtable_s }; #endif +#ifdef CONFIG_NX_SWCURSOR +/* A vtable of raster operation function pointers. The types of the + * function points must match the cursor rasterizer types exported by + * nxglib. + */ + +struct nxbe_cursorops_s +{ + CODE void (*draw)(FAR struct nxbe_state_s *be, int planeno); + CODE void (*erase)(FAR struct nxbe_state_s *be, int planeno); + CODE void (*backup)(FAR struct nxbe_state_s *be, int planeno); +}; +#endif + /* Encapsulates everything needed support window rasterization commands. */ struct nxbe_plane_s { - /* Raster device operation callbacks */ + /* Raster device operations */ struct nxbe_dev_vtable_s dev; #ifdef CONFIG_NX_RAMBACKED - /* Raster per-window framebuffer operation callbacks */ + /* Raster per-window framebuffer operations */ struct nxbe_pwfb_vtable_s pwfb; #endif +#ifdef CONFIG_NX_SWCURSOR + /* Cursor device operations */ + + struct nxbe_cursorops_s cursor; +#endif + /* Framebuffer plane info describing destination video plane */ NX_PLANEINFOTYPE pinfo; @@ -173,24 +194,30 @@ struct nxbe_plane_s struct nxbe_clipops_s { - void (*visible)(FAR struct nxbe_clipops_s *cops, - FAR struct nxbe_plane_s *plane, - FAR const struct nxgl_rect_s *rect); + CODE void (*visible)(FAR struct nxbe_clipops_s *cops, + FAR struct nxbe_plane_s *plane, + FAR const struct nxgl_rect_s *rect); - void (*obscured)(FAR struct nxbe_clipops_s *cops, - FAR struct nxbe_plane_s *plane, - FAR const struct nxgl_rect_s *rect); + CODE void (*obscured)(FAR struct nxbe_clipops_s *cops, + FAR struct nxbe_plane_s *plane, + FAR const struct nxgl_rect_s *rect); }; /* Cursor *******************************************************************/ +/* Cursor state structure */ + #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 */ + nxgl_mxpixel_t color1[CONFIG_NX_NPLANES]; /* Color1 is main color of the cursor */ + nxgl_mxpixel_t color2[CONFIG_NX_NPLANES]; /* Color2 is color of any border */ + nxgl_mxpixel_t color3[CONFIG_NX_NPLANES]; /* Color3 is the blended color */ + size_t allocsize; /* Size of the background allocation */ + FAR const uint8_t *image; /* Cursor image at 2-bits/pixel */ + FAR nxgl_mxpixel_t *bkgd; /* Cursor background in device pixels */ }; #elif defined(CONFIG_NX_HWCURSOR) struct nxbe_cursor_s @@ -325,7 +352,7 @@ void nxbe_cursor_setimage(FAR struct nxbe_state_s *be, #endif /**************************************************************************** - * Name: nxcursor_setposition + * Name: nxbe_cursor_setposition * * Description: * Move the cursor to the specified position @@ -339,8 +366,8 @@ void nxbe_cursor_setimage(FAR struct nxbe_state_s *be, * ****************************************************************************/ -void nxcursor_setposition(FAR struct nxbe_state_s *be, - FAR const struct nxgl_point_s *pos); +void nxbe_cursor_setposition(FAR struct nxbe_state_s *be, + FAR const struct nxgl_point_s *pos); #endif /* CONFIG_NX_SWCURSOR || CONFIG_NX_HWCURSOR */ /**************************************************************************** diff --git a/graphics/nxbe/nxbe_configure.c b/graphics/nxbe/nxbe_configure.c index 33a36164167..5178e817621 100644 --- a/graphics/nxbe/nxbe_configure.c +++ b/graphics/nxbe/nxbe_configure.c @@ -213,6 +213,12 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be) be->plane[i].pwfb.moverectangle = pwfb_moverectangle_8bpp; be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_8bpp; #endif + +#ifdef CONFIG_NX_SWCURSOR + be->plane[i].cursor.draw = nxglib_cursor_draw_8bpp; + be->plane[i].cursor.erase = nxglib_cursor_erase_8bpp; + be->plane[i].cursor.backup = nxglib_cursor_backup_8bpp; +#endif } else #endif @@ -234,6 +240,12 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be) be->plane[i].pwfb.moverectangle = pwfb_moverectangle_16bpp; be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_16bpp; #endif + +#ifdef CONFIG_NX_SWCURSOR + be->plane[i].cursor.draw = nxglib_cursor_draw_16bpp; + be->plane[i].cursor.erase = nxglib_cursor_erase_16bpp; + be->plane[i].cursor.backup = nxglib_cursor_backup_16bpp; +#endif } else #endif @@ -255,6 +267,12 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be) be->plane[i].pwfb.moverectangle = pwfb_moverectangle_24bpp; be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_24bpp; #endif + +#ifdef CONFIG_NX_SWCURSOR + be->plane[i].cursor.draw = nxglib_cursor_draw_24bpp; + be->plane[i].cursor.erase = nxglib_cursor_erase_24bpp; + be->plane[i].cursor.backup = nxglib_cursor_backup_24bpp; +#endif } else #endif @@ -276,6 +294,12 @@ int nxbe_configure(FAR NX_DRIVERTYPE *dev, FAR struct nxbe_state_s *be) be->plane[i].pwfb.moverectangle = pwfb_moverectangle_32bpp; be->plane[i].pwfb.copyrectangle = pwfb_copyrectangle_32bpp; #endif + +#ifdef CONFIG_NX_SWCURSOR + be->plane[i].cursor.draw = nxglib_cursor_draw_32bpp; + be->plane[i].cursor.erase = nxglib_cursor_erase_32bpp; + be->plane[i].cursor.backup = nxglib_cursor_backup_32bpp; +#endif } else #endif diff --git a/graphics/nxbe/nxbe_cursor.c b/graphics/nxbe/nxbe_cursor.c index 76139171445..bffcfd1618e 100644 --- a/graphics/nxbe/nxbe_cursor.c +++ b/graphics/nxbe/nxbe_cursor.c @@ -41,277 +41,13 @@ #include -#include "nxglib_bitblit.h" +#include + +#include "nxglib.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_erasedev - * - * Description: - * Erase the cursor region by writing the saved background to the graphics - * device memory. - * - * REVISIT: This is experimental logic. Its use is restricted to frame- - * buffer device drivers with resolution >= 8 bits-per-pixel. - * - * Input Parameters: - * be - The back-end state structure instance - * plane - The color plane being drawn - * - * Returned Value: - * None - * - ****************************************************************************/ - -static void nxbe_cursor_erasedev(FAR struct nxbe_state_s *be, int plane) -{ - struct nxgl_rect_s intersection; - struct nxgl_point_s origin; - FAR struct nxbe_plane_s *plane; - FAR uint8_t *fbmem; - FAR uint8_t *sline; - FAR uint8_t *dline; - FAR uint8_t *dstart; - FAR NXGL_PIXEL_T *src; - FAR NXGL_PIXEL_T *dest; - nxgl_coord_t width; - nxgl_coord_t height; - nxgl_coord_t sstride; - nxgl_coord_t dstride; - 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 = NXGL_SCALEX(width); - - plane = &wnd->be->plane[0]; - dstride = plane->pinfo.stride; - - /* Get the origin position in the baclgroimd image */ - - nxgl_vectorsubtract(&origin, &intersectioni.pt1, &be->cursor.bounds.pt1); - - /* Get the source and destination addresses */ - - fbmem = (FAR uint8_t *)plane->pinfo.fbmem; - sline = be->cursor.buf + sstride * origin.y + NXGL_SCALEX(origin.y); - dline = (FAR uint8_t *)fbmem + dstride * be->cursor.bounds.pt1.y + - NXGL_SCALEX(be->cursor.bounds.pt1.x); - - /* Erase the old cursor position by copying the previous content */ - - /* Loop for each row */ - - for (row = 0; row < height; row++) - { - /* Reset to the beginning of the line */ - - src = (FAR NXGL_PIXEL_T *)sline; - dest = (FAR NXGL_PIXEL_T *)dline; - - /* Loop for each column */ - - for (col = 0; col < width; col++) - { - *dest++ = *src++; - } - - /* Update the row addresses to the next row */ - - sline += sstride; - dline += dstride; - } - } -} - -/**************************************************************************** - * Name: nxbe_cursor_drawdev - * - * Description: - * Update the cursor region directly in device memory. - * - * REVISIT: This is experimental logic. Its use is restricted to frame- - * buffer device drivers with resolution >= 8 bits-per-pixel. - * - * Input Parameters: - * be - The back-end state structure instance - * plane - The color plane being drawn - * - * Returned Value: - * None - * - ****************************************************************************/ - -static void nxbe_cursor_drawdev(FAR struct nxbe_state_s *be, int plane) -{ - struct nxgl_rect_s intersection; - struct nxgl_point_s origin; - FAR struct nxbe_plane_s *plane; - FAR uint8_t *fbmem; - FAR uint8_t *src; - FAR uint8_t *sline; - FAR uint8_t *dline; - FAR NXGL_PIXEL_T *dest; - nxgl_coord_t width; - nxgl_coord_t height; - nxgl_coord_t sstride; - nxgl_coord_t dstride; - nxgl_coord_t sshift; - int shift; - 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; - - /* Get the origin position in the cursor image */ - - nxgl_vectorsubtract(&origin, &intersectioni.pt1, &be->cursor.bounds.pt1); - - /* 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 + sstride * origin.y + (origin.y >> 2); - dline = (FAR uint8_t *)fbmem + dstride * be->cursor.bounds.pt1.y + - NXGL_SCALEX(be->cursor.bounds.pt1.x); - - sshift = (3 - (origin.y & 3)) << 1; /* MS first {0, 2, 4, 6} */ - - /* Loop for each row */ - - for (row = 0; row < height; row++) - { - /* Reset to the beginning of the line */ - - src = sline; - dest = (FAR NXGL_PIXEL_T *)dline; - shift = sshift; - - /* Loop for each column */ - - for (col = 0; col < width; col++) - { - /* Extract the 2-bit pixel. Data is always packed MS first. - * Shift for first pixel=6, shift for last pixel=0 - */ - - uint8_t spixel = (*src & >> shift) & 3 - - /* Skip over invisible pixels */ - - if (pixel != 0) - { - *dest = nxbe_map_color(be, 0, spixel); - } - - /* Update to the next column */ - - col++; - dest++; - - /* Was that the last pixel in the byte? */ - - if (shift == 0) - { - /* Update source column addresses and reset the shift - * value - */ - - src++; - shift = 6; - } - else - { - /* The shift value is one of {2, 4, 6}. Update the shift - * value following this order: 6, 4, 2, 0 - */ - - shift = (shift - 2) & 6; - } - } - - /* Update the row addresses to the next row */ - - sline += sstride; - dline += dstride; - } - } -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -340,6 +76,17 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable) /* Mark the cursor visible */ be->cursor.visible = true; + +#ifdef CONFIG_NX_SWCURSOR + be->plane[0].cursor.backup(be, 0); /* Save the cursor background image */ + be->plane[0].cursor.draw(be, 0); /* Write the new cursor */ +#else + /* For a hardware cursor, this would require some interaction with the + * grahics device. + */ + +# error Missing logic +#endif } /* Are we disabling the cursor ? */ @@ -349,26 +96,19 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable) /* 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 */ + /* Erase the old cursor image by writing the saved background image. */ - nxbe_cursor_erasedev(be, 0); - nxbe_cursor_drawdev(be, 0); + be->plane[0].cursor.erase(be, 0); /* Erase the old cursor */ #else - /* For a hardware cursor, this would require some interaction with the - * grahics device. - */ + /* For a hardware cursor, this would require some interaction with the + * grahics device. + */ # error Missing logic #endif + } } /**************************************************************************** @@ -386,7 +126,7 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable) * 11 - Color3: A blend color for better imaging (fake anti-aliasing). * * Input Parameters: - * be - The back-end state structure instance + * be - The back-end state structure instance * image - Describes the cursor image in the expected format. * * Returned Value: @@ -396,14 +136,108 @@ void nxbe_cursor_enable(FAR struct nxbe_state_s *be, bool enable) #if defined(CONFIG_NX_HWCURSORIMAGE) || defined(CONFIG_NX_SWCURSOR) void nxbe_cursor_setimage(FAR struct nxbe_state_s *be, - FAR struct nx_cursorimage_s *image); + FAR struct nx_cursorimage_s *image) { -#warning Missing logic +#ifdef CONFIG_NX_SWCURSOR + struct nxgl_size_s oldsize; + size_t allocsize; + unsigned int bpp; + + /* If the cursor is visible, then we need to erase the old cursor from the + * device graphics memory. + */ + + if (be->cursor.visible) + { + /* Erase the old cursor image by writing the saved background image. */ + + be->plane[0].cursor.erase(be, 0); /* Erase the old cursor */ + } + + /* Has the cursor changed size? */ + + oldsize.w = be->cursor.bounds.pt2.x - be->cursor.bounds.pt2.y + 1; + oldsize.h = be->cursor.bounds.pt2.y - be->cursor.bounds.pt2.y + 1; + + if (image->size.w != oldsize.w || image->size.h != oldsize.h) + { + /* Check the size of the allocation we need to hold the backup image. */ + + bpp = be->plane[0].pinfo.bpp; + allocsize = (image->size.w * image->size.h * bpp + 7) >> 3; + + /* Reallocate the buffer only if a larger one is needed */ + + if (allocsize > be->cursor.allocsize) + { + FAR void *tmp = kmm_realloc(be->cursor.bkgd, allocsize); + if (tmp == NULL) + { + goto errout_with_erase; + } + + /* Save the new allocation information */ + + be->cursor.allocsize = allocsize; + be->cursor.bkgd = (FAR nxgl_mxpixel_t *)tmp; + } + + /* Calculate the new image bounds. The position (pt1), does not + * change. + */ + + be->cursor.bounds.pt2.x = be->cursor.bounds.pt1.x + image->size.w - 1; + be->cursor.bounds.pt2.y = be->cursor.bounds.pt1.y + image->size.h - 1; + + /* Read in the new background image */ + + be->plane[0].cursor.backup(be, 0); + } + + /* Save the new colors */ + + nxgl_colorcopy(be->cursor.color1, image->color1); + nxgl_colorcopy(be->cursor.color1, image->color2); + nxgl_colorcopy(be->cursor.color1, image->color3); + + /* Save the new image. This is a reference to an image in user space. + * which we assume will persist while we use it. + * + * REVISIT: There is an issue in KERNEL build mode. For FLAT and + * PROTECTED builds, the cursor image resides in the common application + * space and is assumed to pesist as long as needed. But with the KERNEL + * build, the image will lie in a process space and will not be generally + * available. In that case, we could keep the image in a shared memory + * region or perhaps copy the image into a kernel internal buffer. + * Neither of those are implemented. + */ + + be->cursor.image = image->image; + +errout_with_erase: + /* If the cursor is visible, then put write the new cursor image into + * device graphics memory now. + */ + + if (be->cursor.visible) + { + /* Write the new cursor image to the device graphics memory. */ + + be->plane[0].cursor.draw(be, 0); /* Erase the old cursor */ + } + +#else + /* For a hardware cursor, this would require some interaction with the + * grahics device. + */ + +# error Missing logic +#endif } #endif /**************************************************************************** - * Name: nxcursor_setposition + * Name: nxbe_cursor_setposition * * Description: * Move the cursor to the specified position @@ -417,10 +251,55 @@ void nxbe_cursor_setimage(FAR struct nxbe_state_s *be, * ****************************************************************************/ -void nxcursor_setposition(FAR struct nxbe_state_s *be, - FAR const struct nxgl_point_s *pos) +void nxbe_cursor_setposition(FAR struct nxbe_state_s *be, + FAR const struct nxgl_point_s *pos) { -#warning Missing logic +#ifdef CONFIG_NX_SWCURSOR + nxgl_coord_t dx; + nxgl_coord_t dy; + + /* If the cursor is visible, then we need to erase the cursor from the + * old position in device graphics memory. + */ + + if (be->cursor.visible) + { + /* Erase the old cursor image by writing the saved background image. */ + + be->plane[0].cursor.erase(be, 0); /* Erase the old cursor */ + } + + /* Calculate the cursor movement */ + + dx = pos->x - be->cursor.bounds.pt1.x; + dy = pos->y - be->cursor.bounds.pt1.y; + + /* Calculate the new image bounds. */ + + nxgl_rectoffset(&be->cursor.bounds, &be->cursor.bounds, dx, dy); + + /* Read in the new background image at this offset */ + + be->plane[0].cursor.backup(be, 0); + + /* If the cursor is visible, then put write the new cursor image into + * device graphics memory now. + */ + + if (be->cursor.visible) + { + /* Write the new cursor image to the device graphics memory. */ + + be->plane[0].cursor.draw(be, 0); /* Erase the old cursor */ + } + +#else + /* For a hardware cursor, this would require some interaction with the + * grahics device. + */ + +# error Missing logic +#endif } #endif /* CONFIG_NX_SWCURSOR || CONFIG_NX_HWCURSOR */ diff --git a/graphics/nxglib/.gitignore b/graphics/nxglib/.gitignore index d49f40d897e..861a0270ac7 100644 --- a/graphics/nxglib/.gitignore +++ b/graphics/nxglib/.gitignore @@ -10,4 +10,6 @@ /pwfb_filltrapezoid_*bpp.c /pwfb_moverectangle_*bpp.c /pwfb_copyrectangle_*bpp.c - +/nxglib_cursor_draw_*bpp.c +/nxglib_cursor_erase_*bpp.c +/nxglib_cursor_backup_*bpp.c \ No newline at end of file diff --git a/graphics/nxglib/Make.defs b/graphics/nxglib/Make.defs index 634ac014632..db252c4ba81 100644 --- a/graphics/nxglib/Make.defs +++ b/graphics/nxglib/Make.defs @@ -97,6 +97,19 @@ CSRCS += pwfb_copyrectangle_32bpp.c endif +ifeq ($(CONFIG_NX_SWCURSOR),y) + +CSRCS += nxglib_cursor_draw_8bpp.c nxglib_cursor_draw_16bpp.c +CSRCS += nxglib_cursor_draw_24bpp.c nxglib_cursor_draw_32bpp.c + +CSRCS += nxglib_cursor_erase_8bpp.c nxglib_cursor_erase_16bpp.c +CSRCS += nxglib_cursor_erase_24bpp.c nxglib_cursor_erase_32bpp.c + +CSRCS += nxglib_cursor_backup_8bpp.c nxglib_cursor_backup_16bpp.c +CSRCS += nxglib_cursor_backup_24bpp.c nxglib_cursor_backup_32bpp.c + +endif + DEPPATH += --dep-path nxglib CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)/graphics/nxglib} #VPATH += :nxglib diff --git a/graphics/nxglib/Makefile.cursor b/graphics/nxglib/Makefile.cursor new file mode 100644 index 00000000000..4544dd93379 --- /dev/null +++ b/graphics/nxglib/Makefile.cursor @@ -0,0 +1,105 @@ +############################################################################ +# graphics/nxglib/Makefile.cursor +# +# Copyright (C) 2019 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +ifeq ($(NXGLIB_BITSPERPIXEL),8) +NXGLIB_SUFFIX := _8bpp +DRAW_CSRC := nxglib_cursor_draw_8bpp.c +ERASE_CSRC := nxglib_cursor_erase_8bpp.c +BACKUP_CSRC := nxglib_cursor_backup_8bpp.c +endif +ifeq ($(NXGLIB_BITSPERPIXEL),16) +NXGLIB_SUFFIX := _16bpp +DRAW_CSRC := nxglib_cursor_draw_16bpp.c +ERASE_CSRC := nxglib_cursor_erase_16bpp.c +BACKUP_CSRC := nxglib_cursor_backup_16bpp.c +endif +ifeq ($(NXGLIB_BITSPERPIXEL),24) +NXGLIB_SUFFIX := _24bpp +DRAW_CSRC := nxglib_cursor_draw_24bpp.c +ERASE_CSRC := nxglib_cursor_erase_24bpp.c +BACKUP_CSRC := nxglib_cursor_backup_24bpp.c +endif +ifeq ($(NXGLIB_BITSPERPIXEL),32) +NXGLIB_SUFFIX := _32bpp +DRAW_CSRC := nxglib_cursor_draw_32bpp.c +ERASE_CSRC := nxglib_cursor_erase_32bpp.c +BACKUP_CSRC := nxglib_cursor_backup_32bpp.c +endif + +CPPFLAGS += -DNXGLIB_BITSPERPIXEL=$(NXGLIB_BITSPERPIXEL) +CPPFLAGS += -DNXGLIB_SUFFIX=$(NXGLIB_SUFFIX) + +DRAW_TMP = $(DRAW_CSRC:.c=.i) +ERASE_TMP = $(ERASE_CSRC:.c=.i) +BACKUP_TMP = $(BACKUP_CSRC:.c=.i) + +GEN_CSRCS = $(DRAW_CSRC) $(ERASE_CSRC) $(BACKUP_CSRC) + +BLITDIR = cursor + +all: $(GEN_CSRCS) +.PHONY : clean distclean + +$(DRAW_CSRC) : $(BLITDIR)/nxglib_cursor_draw.c nxglib_bitblit.h +ifneq ($(NXGLIB_BITSPERPIXEL),) + $(call PREPROCESS, $(BLITDIR)/nxglib_cursor_draw.c, $(DRAW_TMP)) + $(Q) cat $(DRAW_TMP) | sed -e "/^#/d" >$@ + $(Q) rm -f $(DRAW_TMP) +endif + +$(ERASE_CSRC) : $(BLITDIR)/nxglib_cursor_erase.c nxglib_bitblit.h +ifneq ($(NXGLIB_BITSPERPIXEL),) + $(call PREPROCESS, $(BLITDIR)/nxglib_cursor_erase.c, $(ERASE_TMP)) + $(Q) cat $(ERASE_TMP) | sed -e "/^#/d" >$@ + $(Q) rm -f $(ERASE_TMP) +endif + +$(BACKUP_CSRC) : $(BLITDIR)/nxglib_cursor_backup.c nxglib_bitblit.h +ifneq ($(NXGLIB_BITSPERPIXEL),) + $(call PREPROCESS, $(BLITDIR)/nxglib_cursor_backup.c, $(BACKUP_TMP)) + $(Q) cat $(BACKUP_TMP) | sed -e "/^#/d" >$@ + $(Q) rm -f $(BACKUP_TMP) +endif + +clean: + $(call DELFILE, *.i) + $(call CLEAN) + +distclean: clean + $(call DELFILE, nxglib_cursor_draw_*bpp.c) + $(call DELFILE, nxglib_cursor_erase_*bpp.c) + $(call DELFILE, nxglib_cursor_backup_*bpp.c) diff --git a/graphics/nxglib/cursor/nxglib_cursor_backup.c b/graphics/nxglib/cursor/nxglib_cursor_backup.c new file mode 100644 index 00000000000..823c2c881b4 --- /dev/null +++ b/graphics/nxglib/cursor/nxglib_cursor_backup.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * graphics/nxglib/nxglib_cursor_backup.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxglib_bitblit.h" +#include "../nxbe/nxbe.h" +#include "nxglib.h" + +#ifdef CONFIG_NX_SWCURSOR + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxglib_cursor_backup + * + * Description: + * Saved the cursor background data from the device graphics memory into an + * internal save area. This saved image will be used to "erase" the cursor + * when necessary. + * + * Input Parameters: + * be - The back-end state structure instance + * planeno - The color plane being drawn + * + * Returned Value: + * None + * + ****************************************************************************/ + +void NXGL_FUNCNAME(nxglib_cursor_backup, NXGLIB_SUFFIX) +(FAR struct nxbe_state_s *be, int planeno) +{ + struct nxgl_rect_s intersection; + struct nxgl_point_s origin; + FAR struct nxbe_plane_s *plane; + FAR uint8_t *fbmem; + FAR uint8_t *sline; + FAR uint8_t *dline; + FAR NXGL_PIXEL_T *src; + FAR NXGL_PIXEL_T *dest; + nxgl_coord_t width; + nxgl_coord_t height; + nxgl_coord_t sstride; + nxgl_coord_t dstride; + int row; + int col; + + /* Handle the case some or all of the backup image is off of the display. */ + + nxgl_rectintersect(&intersection, &be->cursor.bounds, &be->bkgd.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.y + 1; + + /* Get the width of the images in bytes. */ + + plane = &be->plane[planeno]; + sstride = plane->pinfo.stride; + + dstride = NXGL_SCALEX(width); + + /* Get the origin position in the background image */ + + nxgl_vectsubtract(&origin, &intersection.pt1, &be->cursor.bounds.pt1); + + /* Get the source and destination addresses */ + + fbmem = (FAR uint8_t *)plane->pinfo.fbmem; + sline = (FAR uint8_t *)fbmem + sstride * be->cursor.bounds.pt1.y + + NXGL_SCALEX(be->cursor.bounds.pt1.x); + dline = (FAR uint8_t *)be->cursor.bkgd + dstride * origin.y + + NXGL_SCALEX(origin.y); + + /* Save the cursor background by copying the device graphics memory */ + + /* Loop for each row */ + + for (row = 0; row < height; row++) + { + /* Reset to the beginning of the line */ + + src = (FAR NXGL_PIXEL_T *)sline; + dest = (FAR NXGL_PIXEL_T *)dline; + + /* Loop for each column */ + + for (col = 0; col < width; col++) + { + *dest++ = *src++; + } + + /* Update the row addresses to the next row */ + + sline += sstride; + dline += dstride; + } + } +} +#endif /* CONFIG_NX_SWCURSOR */ diff --git a/graphics/nxglib/cursor/nxglib_cursor_draw.c b/graphics/nxglib/cursor/nxglib_cursor_draw.c new file mode 100644 index 00000000000..597595fa6e9 --- /dev/null +++ b/graphics/nxglib/cursor/nxglib_cursor_draw.c @@ -0,0 +1,234 @@ +/**************************************************************************** + * graphics/nxglib/nxglib_cursor_draw.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxglib_bitblit.h" +#include "../nxbe/nxbe.h" +#include "nxglib.h" + +#ifdef CONFIG_NX_SWCURSOR + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxbe_map_color + * + * Description: + * Map a 2-bit cursor pixel value to a device pixel value + * + * REVISIT: If we really were to support multiple displays (or planes) + * with differing pixel depth, then the cursor.color1,2,3 would be + * insufficient: There would have to be multiple color sets for each + * plane. + * + * Input Parameters: + * be - The back-end state structure instance + * pixel - Pixel to be mapped + * + * Returned Value: + * The mapped pixel. + * + ****************************************************************************/ + +static NXGL_PIXEL_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; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxglib_cursor_draw + * + * Description: + * Update the cursor region by drawing directly in device memory. + * + * Input Parameters: + * be - The back-end state structure instance + * planeno - The color plane being drawn + * + * Returned Value: + * None + * + ****************************************************************************/ + +void NXGL_FUNCNAME(nxglib_cursor_draw, NXGLIB_SUFFIX) +(FAR struct nxbe_state_s *be, int planeno) +{ + struct nxgl_rect_s intersection; + struct nxgl_point_s origin; + FAR struct nxbe_plane_s *plane; + FAR uint8_t *fbmem; + FAR uint8_t *src; + FAR uint8_t *sline; + FAR uint8_t *dline; + FAR NXGL_PIXEL_T *dest; + nxgl_coord_t width; + nxgl_coord_t height; + nxgl_coord_t sstride; + nxgl_coord_t dstride; + nxgl_coord_t sshift; + int shift; + int row; + int col; + + /* Handle the case some or all of the cursor image is off of the display. */ + + nxgl_rectintersect(&intersection, &be->cursor.bounds, &be->bkgd.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.y + 1; + + /* Get the width of the images in bytes. */ + + sstride = (width + 3) >> 2; /* 2 bits per pixel, 4 pixels per byte */ + + plane = &be->plane[planeno]; + dstride = plane->pinfo.stride; + + /* Get the origin position in the cursor image */ + + nxgl_vectsubtract(&origin, &intersection.pt1, &be->cursor.bounds.pt1); + + /* 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 + sstride * origin.y + (origin.y >> 2); + dline = (FAR uint8_t *)fbmem + dstride * be->cursor.bounds.pt1.y + + NXGL_SCALEX(be->cursor.bounds.pt1.x); + + sshift = (3 - (origin.y & 3)) << 1; /* MS first {0, 2, 4, 6} */ + + /* Loop for each row */ + + for (row = 0; row < height; row++) + { + /* Reset to the beginning of the line */ + + src = sline; + dest = (FAR NXGL_PIXEL_T *)dline; + shift = sshift; + + /* Loop for each column */ + + for (col = 0; col < width; col++) + { + /* Extract the 2-bit pixel. Data is always packed MS first. + * Shift for first pixel=6, shift for last pixel=0 + */ + + uint8_t pixel = (*src >> shift) & 3; + + /* Skip over invisible pixels */ + + if (pixel != 0) + { + *dest = nxbe_map_color(be, 0, pixel); + } + + /* Update to the next column */ + + col++; + dest++; + + /* Was that the last pixel in the byte? */ + + if (shift == 0) + { + /* Update source column addresses and reset the shift + * value + */ + + src++; + shift = 6; + } + else + { + /* The shift value is one of {2, 4, 6}. Update the shift + * value following this order: 6, 4, 2, 0 + */ + + shift = (shift - 2) & 6; + } + } + + /* Update the row addresses to the next row */ + + sline += sstride; + dline += dstride; + } + } +} + +#endif /* CONFIG_NX_SWCURSOR */ diff --git a/graphics/nxglib/cursor/nxglib_cursor_erase.c b/graphics/nxglib/cursor/nxglib_cursor_erase.c new file mode 100644 index 00000000000..2a08d2c6e82 --- /dev/null +++ b/graphics/nxglib/cursor/nxglib_cursor_erase.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * graphics/nxglib/nxglib_cursor_erase.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "nxglib_bitblit.h" +#include "../nxbe/nxbe.h" +#include "nxglib.h" + +#ifdef CONFIG_NX_SWCURSOR + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nxglib_cursor_erase + * + * Description: + * Erase the cursor region by writing the saved background to the graphics + * device memory. + * + * Input Parameters: + * be - The back-end state structure instance + * planeno - The color plane being drawn + * + * Returned Value: + * None + * + ****************************************************************************/ + +void NXGL_FUNCNAME(nxglib_cursor_erase, NXGLIB_SUFFIX) +(FAR struct nxbe_state_s *be, int planeno) +{ + struct nxgl_rect_s intersection; + struct nxgl_point_s origin; + FAR struct nxbe_plane_s *plane; + FAR uint8_t *fbmem; + FAR uint8_t *sline; + FAR uint8_t *dline; + FAR NXGL_PIXEL_T *src; + FAR NXGL_PIXEL_T *dest; + nxgl_coord_t width; + nxgl_coord_t height; + nxgl_coord_t sstride; + nxgl_coord_t dstride; + int row; + int col; + + /* Handle the case some or all of the cursor image is off of the display. */ + + nxgl_rectintersect(&intersection, &be->cursor.bounds, &be->bkgd.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.y + 1; + + /* Get the width of the images in bytes. */ + + sstride = NXGL_SCALEX(width); + + plane = &be->plane[planeno]; + dstride = plane->pinfo.stride; + + /* Get the origin position in the background image */ + + nxgl_vectsubtract(&origin, &intersection.pt1, &be->cursor.bounds.pt1); + + /* Get the source and destination addresses */ + + fbmem = (FAR uint8_t *)plane->pinfo.fbmem; + sline = (FAR uint8_t *)be->cursor.bkgd + sstride * origin.y + + NXGL_SCALEX(origin.y); + dline = (FAR uint8_t *)fbmem + dstride * be->cursor.bounds.pt1.y + + NXGL_SCALEX(be->cursor.bounds.pt1.x); + + /* Erase the old cursor position by copying the previous content */ + + /* Loop for each row */ + + for (row = 0; row < height; row++) + { + /* Reset to the beginning of the line */ + + src = (FAR NXGL_PIXEL_T *)sline; + dest = (FAR NXGL_PIXEL_T *)dline; + + /* Loop for each column */ + + for (col = 0; col < width; col++) + { + *dest++ = *src++; + } + + /* Update the row addresses to the next row */ + + sline += sstride; + dline += dstride; + } + } +} + +#endif /* CONFIG_NX_SWCURSOR */ diff --git a/graphics/nxglib/nxglib.h b/graphics/nxglib/nxglib.h index 9621d0d6cc4..737b8ad6532 100644 --- a/graphics/nxglib/nxglib.h +++ b/graphics/nxglib/nxglib.h @@ -453,6 +453,55 @@ void pwfb_copyrectangle_32bpp(FAR struct nxbe_window_s *bwnd, unsigned int srcstride); #endif +/**************************************************************************** + * Name: nxgl_cursor_draw_*bpp + * + * Description: + * Draw the cursor image into the specified position in the graphics memory. + * + ****************************************************************************/ + +struct nxbe_state_s; /* Forward reference */ + +#ifdef CONFIG_NX_SWCURSOR +void nxglib_cursor_draw_8bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_draw_16bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_draw_24bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_draw_32bpp(FAR struct nxbe_state_s *be, int planeno); +#endif + +/**************************************************************************** + * Name: nxgl_cursor_erase_*bpp + * + * Description: + * Erase the cursor by copying the saved background image into the graphics + * memory. + * + ****************************************************************************/ + +#ifdef CONFIG_NX_SWCURSOR +void nxglib_cursor_erase_8bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_erase_16bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_erase_24bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_erase_32bpp(FAR struct nxbe_state_s *be, int planeno); +#endif + +/**************************************************************************** + * Name: nxgl_cursor_backup_*bpp + * + * Description: + * Save the backgroud image for subsequent use to erase the cursor from the + * device graphics memory. + * + ****************************************************************************/ + +#ifdef CONFIG_NX_SWCURSOR +void nxglib_cursor_backup_8bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_backup_16bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_backup_24bpp(FAR struct nxbe_state_s *be, int planeno); +void nxglib_cursor_backup_32bpp(FAR struct nxbe_state_s *be, int planeno); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/graphics/nxmu/nxmu_server.c b/graphics/nxmu/nxmu_server.c index daf556d3550..b0b999bbbf5 100644 --- a/graphics/nxmu/nxmu_server.c +++ b/graphics/nxmu/nxmu_server.c @@ -380,7 +380,7 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_SVRMSG_CURSOR_ENABLE: /* Enable/disable cursor */ { FAR struct nxsvrmsg_curenable_s *enabmsg = (FAR struct nxsvrmsg_curenable_s *)buffer; - nxbe_cursor_enable(&nxwm.be, enabmsg->enable); + nxbe_cursor_enable(&nxmu.be, enabmsg->enable); } break; @@ -388,14 +388,14 @@ int nx_runinstance(FAR const char *mqname, FAR NX_DRIVERTYPE *dev) case NX_SVRMSG_CURSOR_IMAGE: /* Set cursor image */ { FAR struct nxsvrmsg_curimage_s *imgmsg = (FAR struct nxsvrmsg_curimage_s *)buffer; - nxbe_cursor_setimage(&nxwm.be, imgmsg->image); + nxbe_cursor_setimage(&nxmu.be, &imgmsg->image); } break; #endif case NX_SVRMSG_CURSOR_SETPOS: /* Set cursor position */ { FAR struct nxsvrmsg_curpos_s *posmsg = (FAR struct nxsvrmsg_curpos_s *)buffer; - nxbe_cursor_setposition(&nxwm.be, &posmsg->pos); + nxbe_cursor_setposition(&nxmu.be, &posmsg->pos); } break; #endif diff --git a/include/nuttx/nx/nxcursor.h b/include/nuttx/nx/nxcursor.h index 52b519c985d..27166182967 100644 --- a/include/nuttx/nx/nxcursor.h +++ b/include/nuttx/nx/nxcursor.h @@ -59,6 +59,36 @@ extern "C" #define EXTERN extern #endif +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* The current software cursor implementation is only available under the + * following conditions: + * + * 1. Using a framebuffer hardware interface. This is because the logic to + * implement this feature on top of the LCD interface has not been + * implemented. + * 2. Pixel depth is greater then or equal to 8-bits (8-bpp, 16-bpp, + * 24/32/-bpp). This is because the logic to handle pixels smaller than + * 1-byte has not been implemented, + * 3. For FLAT and PROTECTED builds only. In those builds, the cursor + * image resides in the common application space and is assumed to pesist + * as long as needed. But with the KERNEL build, the image will lie in + * a process space and will not be generally available. In that case, + * we could keep the image in a shared memory region or perhaps copy the + * image into a kernel internal buffer. Neither of those are implemented. + */ + +#if (defined(CONFIG_NX_SWCURSOR) && \ + (defined(CONFIG_NX_LCDDRIVER) || !defined(CONFIG_NX_DISABLE_1BPP) || \ + !defined(CONFIG_NX_DISABLE_2BPP) || !defined(CONFIG_NX_DISABLE_4BPP) || \ + defined(CONFIG_BUILD_KERNEL))) +# undef CONFIG_NX_NOCURSOR +# undef CONFIG_NX_SWCURSOR +# define CONFIG_NX_NOCURSOR 1 +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/include/nuttx/nx/nxglib.h b/include/nuttx/nx/nxglib.h index 9be448de49e..a84d7b57df8 100644 --- a/include/nuttx/nx/nxglib.h +++ b/include/nuttx/nx/nxglib.h @@ -185,7 +185,7 @@ void nxgl_vectoradd(FAR struct nxgl_point_s *dest, FAR const struct nxgl_point_s *v2); /**************************************************************************** - * Name: nxgl_vectorsubtract + * Name: nxgl_vectsubtract * * Description: * Add subtract vector v2 from vector v1 and return the result in vector dest diff --git a/libs/libnx/nxmu/nx_cursor.c b/libs/libnx/nxmu/nx_cursor.c index 34f50e5913c..321ff8f0b16 100644 --- a/libs/libnx/nxmu/nx_cursor.c +++ b/libs/libnx/nxmu/nx_cursor.c @@ -40,11 +40,15 @@ #include #include +#include #include +#include +#include +#include #include -#ifndef defined(CONFIG_NX_SWCURSOR) || defined(CONFIG_NX_HWCURSOR) +#if defined(CONFIG_NX_SWCURSOR) || defined(CONFIG_NX_HWCURSOR) /**************************************************************************** * Public Functions @@ -67,7 +71,7 @@ int nxcursor_enable(NXHANDLE hnd, bool enable) { - FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)handle; + FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)hnd; struct nxsvrmsg_curenable_s outmsg; int ret; @@ -81,7 +85,7 @@ int nxcursor_enable(NXHANDLE hnd, bool enable) { gerr("ERROR: nxmu_sendserver() returned %d\n", ret); set_errno(-ret); - return ERROR + return ERROR; } return OK; @@ -117,7 +121,7 @@ int nxcursor_enable(NXHANDLE hnd, bool enable) #if defined(CONFIG_NX_HWCURSORIMAGE) || defined(CONFIG_NX_SWCURSOR) int nxcursor_setimage(NXHANDLE hnd, FAR struct nx_cursorimage_s *image) { - FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)handle; + FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)hnd; struct nxsvrmsg_curimage_s outmsg; int ret; @@ -126,13 +130,14 @@ int nxcursor_setimage(NXHANDLE hnd, FAR struct nx_cursorimage_s *image) /* Send the new cursor image to the server */ outmsg.msgid = NX_SVRMSG_CURSOR_IMAGE; - outmsg.image.size.x = image->size.x; - outmsg.image.size.y = image->size.y; - outmsg.image.color1 = image->color1; - outmsg.image.color2 = image->color2; - outmsg.image.color3 = image->color3; + outmsg.image.size.w = image->size.w; + outmsg.image.size.h = image->size.h; outmsg.image.image = image->image; /* The user pointer is sent, no data */ + nxgl_colorcopy(outmsg.image.color1, image->color1); + nxgl_colorcopy(outmsg.image.color1, image->color1); + nxgl_colorcopy(outmsg.image.color1, image->color1); + /* We will finish the teardown upon receipt of the DISCONNECTED message */ ret = nxmu_sendserver(conn, &outmsg, sizeof(struct nxsvrmsg_curimage_s)); @@ -140,7 +145,7 @@ int nxcursor_setimage(NXHANDLE hnd, FAR struct nx_cursorimage_s *image) { gerr("ERROR: nxmu_sendserver() returned %d\n", ret); set_errno(-ret); - return ERROR + return ERROR; } return OK; @@ -164,7 +169,7 @@ int nxcursor_setimage(NXHANDLE hnd, FAR struct nx_cursorimage_s *image) int nxcursor_setposition(NXHANDLE hnd, FAR const struct nxgl_point_s *pos) { - FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)handle; + FAR struct nxmu_conn_s *conn = (FAR struct nxmu_conn_s *)hnd; struct nxsvrmsg_curpos_s outmsg; int ret; @@ -183,7 +188,7 @@ int nxcursor_setposition(NXHANDLE hnd, FAR const struct nxgl_point_s *pos) { gerr("ERROR: nxmu_sendserver() returned %d\n", ret); set_errno(-ret); - return ERROR + return ERROR; } return OK;