From 65555542e5029e5e21ee2df259c5b7d4e609a9d8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 18 Nov 2017 15:27:12 -0600 Subject: [PATCH] apps/graphics/pdcurs34/nuttx: Add framebuffer initialization logic. --- graphics/pdcurs34/IMPLEMNT | 6 +- graphics/pdcurs34/nuttx/Kconfig | 4 + graphics/pdcurs34/nuttx/Make.defs | 2 +- graphics/pdcurs34/nuttx/pdcdisp.c | 23 ++++ graphics/pdcurs34/nuttx/pdckbd.c | 14 +++ graphics/pdcurs34/nuttx/pdcnuttx.h | 94 ++++++++++++---- graphics/pdcurs34/nuttx/pdcscrn.c | 165 ++++++++++++++++++++++++++++- 7 files changed, 281 insertions(+), 27 deletions(-) diff --git a/graphics/pdcurs34/IMPLEMNT b/graphics/pdcurs34/IMPLEMNT index 7a52599fe..adbccae67 100644 --- a/graphics/pdcurs34/IMPLEMNT +++ b/graphics/pdcurs34/IMPLEMNT @@ -34,11 +34,11 @@ DATA STRUCTURES A port of PDCurses must provide acs_map[], a 128-element array of chtypes, with values laid out based on the Alternate Character Set of -the VT100 (see curses.h). PDC_transform_line() must use this table; when +the VT100 (see curses.h). PDC_transform_line() must use this table; when it encounters a chtype with the A_ALTCHARSET flag set, and an A_CHARTEXT value in the range 0-127, it must render it using the A_CHARTEXT portion of the corresponding value from this table, instead of the original -value. Also, values may be read from this table by apps, and passed +value. Also, values may be read from this table by apps, and passed through functions such as waddch(), which does no special processing on control characters (0-31 and 127) when the A_ALTCHARSET flag is set. Thus, any control characters used in acs_map[] should also have the @@ -101,7 +101,7 @@ internally from PDC_scr_open(), but this is not required.) int PDC_get_cursor_mode(void); Returns the size/shape of the cursor. The format of the result is -unspecified, except that it must be returned as an int. This function is +unspecified, except that it must be returned as an int. This function is called from initscr(), and the result is stored in SP->orig_cursor, which is used by PDC_curs_set() to determine the size/shape of the cursor in normal visibility mode (curs_set(1)). diff --git a/graphics/pdcurs34/nuttx/Kconfig b/graphics/pdcurs34/nuttx/Kconfig index a7063a1b2..cf29ebc11 100644 --- a/graphics/pdcurs34/nuttx/Kconfig +++ b/graphics/pdcurs34/nuttx/Kconfig @@ -3,6 +3,10 @@ # see the file kconfig-language.txt in the NuttX tools repository. # +config PDCURSES_FBDEV + string "Framebuffer device" + default "/dev/fb0" + choice prompt "TUI Font Selection" default PDCURSES_FOUNT_6X9 diff --git a/graphics/pdcurs34/nuttx/Make.defs b/graphics/pdcurs34/nuttx/Make.defs index 1258612f7..6d3b049e0 100644 --- a/graphics/pdcurs34/nuttx/Make.defs +++ b/graphics/pdcurs34/nuttx/Make.defs @@ -34,7 +34,7 @@ ############################################################################ CSRCS += pdcclip.c pdcdisp.c pdcgetsc.c pdckbd.c pdcscrn.c pdcsetsc.c -CRCCS += pdcutil.c +CSRCS += pdcutil.c DEPPATH += --dep-path nuttx VPATH += :nuttx diff --git a/graphics/pdcurs34/nuttx/pdcdisp.c b/graphics/pdcurs34/nuttx/pdcdisp.c index bc220b0a2..f4ccb677e 100644 --- a/graphics/pdcurs34/nuttx/pdcdisp.c +++ b/graphics/pdcurs34/nuttx/pdcdisp.c @@ -41,6 +41,29 @@ #include "pdcnuttx.h" +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* A port of PDCurses must provide acs_map[], a 128-element array of chtypes, + * with values laid out based on the Alternate Character Set of the VT100 + * (see curses.h). PDC_transform_line() must use this table; when it + * encounters a chtype with the A_ALTCHARSET flag set, and an A_CHARTEXT + * value in the range 0-127, it must render it using the A_CHARTEXT portion + * of the corresponding value from this table, instead of the original + * value. Also, values may be read from this table by apps, and passed + * through functions such as waddch(), which does no special processing on + * control characters (0-31 and 127) when the A_ALTCHARSET flag is set. + * Thus, any control characters used in acs_map[] should also have the + * A_ALTCHARSET flag set. Implementations should provide suitable values + * for all the ACS_ macros defined in curses.h; other values in the table + * should be filled with their own indices (e.g., acs_map['E'] == 'E'). The + * table can be either hardwired, or filled by PDC_scr_open(). Existing + * ports define it in pdcdisp.c, but this is not required. + */ + +chtype acs_map[128]; + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/graphics/pdcurs34/nuttx/pdckbd.c b/graphics/pdcurs34/nuttx/pdckbd.c index 50a69a9f0..483c4af20 100644 --- a/graphics/pdcurs34/nuttx/pdckbd.c +++ b/graphics/pdcurs34/nuttx/pdckbd.c @@ -39,6 +39,20 @@ #include "pdcnuttx.h" +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Key modifiers. The OR of any of: + * + * PDC_KEY_MODIFIER_SHIFT; + * PDC_KEY_MODIFIER_CONTROL; + * PDC_KEY_MODIFIER_ALT; + * PDC_KEY_MODIFIER_NUMLOCK; + */ + +unsigned long pdc_key_modifiers; + /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/graphics/pdcurs34/nuttx/pdcnuttx.h b/graphics/pdcurs34/nuttx/pdcnuttx.h index c2c17c45f..fac884e84 100644 --- a/graphics/pdcurs34/nuttx/pdcnuttx.h +++ b/graphics/pdcurs34/nuttx/pdcnuttx.h @@ -41,7 +41,10 @@ ****************************************************************************/ #include "nuttx/config.h" + +#include "nuttx/nx/nx.h" #include "nuttx/nx/nxfonts.h" + #include "curspriv.h" /**************************************************************************** @@ -49,45 +52,98 @@ ****************************************************************************/ #if defined(CONFIG_PDCURSES_FOUNT_4X6) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_4X6 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_4X6 #elif defined(CONFIG_PDCURSES_FOUNT_5X7) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_5X7 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_5X7 #elif defined(CONFIG_PDCURSES_FOUNT_5X8) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_5X8 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_5X8 #elif defined(CONFIG_PDCURSES_FOUNT_6X9) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_6X9 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_6X9 #elif defined(CONFIG_PDCURSES_FOUNT_6X10) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_6X10 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_6X10 #elif defined(CONFIG_PDCURSES_FOUNT_6X12) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_6X12 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_6X12 #elif defined(CONFIG_PDCURSES_FOUNT_6X13) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_6X13 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_6X13 #elif defined(CONFIG_PDCURSES_FOUNT_6X13B) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_6X13B +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_6X13B #elif defined(CONFIG_PDCURSES_FOUNT_7X13) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_7X13 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_7X13 #elif defined(CONFIG_PDCURSES_FOUNT_7X13B) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_7X13B +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_7X13B #elif defined(CONFIG_PDCURSES_FOUNT_7X14) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_7X14 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_7X14 #elif defined(CONFIG_PDCURSES_FOUNT_7X14B) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_7X14B +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_7X14B #elif defined(CONFIG_PDCURSES_FOUNT_8X13) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_8X13 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_8X13 #elif defined(CONFIG_PDCURSES_FOUNT_8X13B) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_8X13B +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_8X13B #elif defined(CONFIG_PDCURSES_FOUNT_9X15) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_9X15 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_9X15 #elif defined(CONFIG_PDCURSES_FOUNT_9X15B) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_9X15B +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_9X15B #elif defined(CONFIG_PDCURSES_FOUNT_9X18) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_9X18 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_9X18 #elif defined(CONFIG_PDCURSES_FOUNT_9X18B) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_9X18B +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_9X18B #elif defined(CONFIG_PDCURSES_FOUNT_10X20) -# define PDCURSES_FONTID ID FONTID_X11_MISC_FIXED_10X20 +# define PDCURSES_FONTID FONTID_X11_MISC_FIXED_10X20 #else # error No fixed width font selected #endif +/**************************************************************************** + * Private Types + ****************************************************************************/ + +#if defined(__cplusplus) +extern "C" +{ +# define EXTERN extern "C" +#else +# define EXTERN extern +#endif + +/* This structure provides the overall state of the frambuffer device */ + +struct pdc_fbstate_s +{ + /* Framebuffer */ + + int fd; /* Open framebuffer driver file descriptor */ + fb_coord_t xres; /* Horizontal resolution in pixel columns */ + fb_coord_t yres; /* Vertical resolution in pixel rows */ + fb_coord_t stride; /* Length of a line in bytes */ + uint8_t bpp; /* Bits per pixel */ + FAR void *fbmem; /* Start of framebuffer memory */ + + /* Font */ + + NXHANDLE hfont; /* Handled uses to access selected font */ + uint8_t fheight; /* Height of the font in pixels */ + uint8_t fwidth; /* Width of the font in pixels */ + + /* Drawable area (See also SP->lines and SP->cols) */ + + uint8_t hoffset; /* Offset from left of display in pixels */ + uint8_t voffset; /* Offset from top of display in lines */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This singleton represents the state of frame buffer device. pdcurses + * depends on global variables and, hence, can never support more than a + * single framebuffer instance in the same address space. + */ + +EXTERN struct pdc_fbstate_s g_pdc_fbstate; + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* __APPS_GRAPHICS_PDCURS34_NUTTX_PDCNUTTX_H */ diff --git a/graphics/pdcurs34/nuttx/pdcscrn.c b/graphics/pdcurs34/nuttx/pdcscrn.c index cda6b4fc6..6fc8d93a1 100644 --- a/graphics/pdcurs34/nuttx/pdcscrn.c +++ b/graphics/pdcurs34/nuttx/pdcscrn.c @@ -37,8 +37,27 @@ * Included Files ****************************************************************************/ +#include + +#include +#include +#include +#include +#include + #include "pdcnuttx.h" +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* This singleton represents the state of frame buffer device. pdcurses + * depends on global variables and, hence, can never support more than a + * single framebuffer instance in the same address space. + */ + +struct pdc_fbstate_s g_pdc_fbstate; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -79,16 +98,16 @@ void PDC_scr_free(void) * Name: PDC_scr_open * * Description: - * The platform-specific part of initscr(). It's actually called from + * The platform-specific part of initscr(). It's actually called from * Xinitscr(); the arguments, if present, correspond to those used with * main(), and may be used to set the title of the terminal window, or for * other, platform-specific purposes. (The arguments are currently used - * only in X11.) PDC_scr_open() must allocate memory for SP, and must + * only in X11.) PDC_scr_open() must allocate memory for SP, and must * initialize acs_map[] (unless it's preset) and several members of SP, * including lines, cols, mouse_wait, orig_attr (and if orig_attr is true, * orig_fore and orig_back), mono, _restore and _preserve. (Although SP is * used the same way in all ports, it's allocated here in order to allow - * the X11 port to map it to a block of shared memory.) If using an + * the X11 port to map it to a block of shared memory.) If using an * existing terminal, and the environment variable PDC_RESTORE_SCREEN is * set, this function may also store the existing screen image for later * restoration by PDC_scr_close(). @@ -97,8 +116,146 @@ void PDC_scr_free(void) int PDC_scr_open(int argc, char **argv) { + struct fb_videoinfo_s vinfo; + struct fb_planeinfo_s pinfo; + FAR const struct nx_font_s *fontset; + uint32_t bitwidth; + int ret; + PDC_LOG(("PDC_scr_open() - called\n")); -#warning Missing logic + + /* Allocate the global instance of SP */ + + SP = (SCREEN *)zalloc(sizeof(SCREEN)); + if (SP == NULL) + { + PDC_LOG(("ERROR: Failed to allocate SP\n")); + return ERR; + } + + /* Open the framebuffer driver */ + + g_pdc_fbstate.fd = open(CONFIG_PDCURSES_FBDEV, O_RDWR); + if (g_pdc_fbstate.fd < 0) + { + PDC_LOG(("ERROR: Failed to open %s: %d\n", + CONFIG_PDCURSES_FBDEV, errno)); + goto errout_with_sp; + } + + /* Get the characteristics of the framebuffer */ + + ret = ioctl(g_pdc_fbstate.fd, FBIOGET_VIDEOINFO, + (unsigned long)((uintptr_t)&vinfo)); + if (ret < 0) + { + PDC_LOG(("ERROR: ioctl(FBIOGET_VIDEOINFO) failed: %d\n", errno)); + goto errout_with_fd; + } + + PDC_LOG(("VideoInfo:\n")); + PDC_LOG((" fmt: %u\n", vinfo.fmt)); + PDC_LOG((" xres: %u\n", vinfo.xres)); + PDC_LOG((" yres: %u\n", vinfo.yres)); + PDC_LOG((" nplanes: %u\n", vinfo.nplanes)); + + g_pdc_fbstate.xres = vinfo.xres; /* Horizontal resolution in pixel columns */ + g_pdc_fbstate.yres = vinfo.yres; /* Vertical resolution in pixel rows */ + + ret = ioctl(g_pdc_fbstate.fd, FBIOGET_PLANEINFO, + (unsigned long)((uintptr_t)&pinfo)); + if (ret < 0) + { + PDC_LOG(("ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n", errno)); + goto errout_with_fd; + } + + PDC_LOG(("PlaneInfo (plane 0):\n")); + PDC_LOG((" fbmem: %p\n", pinfo.fbmem)); + PDC_LOG((" fblen: %lu\n", (unsigned long)pinfo.fblen)); + PDC_LOG((" stride: %u\n", pinfo.stride)); + PDC_LOG((" display: %u\n", pinfo.display)); + PDC_LOG((" bpp: %u\n", pinfo.bpp)); + + g_pdc_fbstate.stride = pinfo.stride; /* Length of a line in bytes */ + g_pdc_fbstate.bpp = pinfo.bpp; /* Bits per pixel */ + + /* Only these pixel depths are supported. vinfo.fmt is ignored, only + * certain color formats are supported. + */ + + if (pinfo.bpp != 32 && pinfo.bpp != 16 && + pinfo.bpp != 8 && pinfo.bpp != 1) + { + PDC_LOG(("ERROR: bpp=%u not supported\n", pinfo.bpp)); + goto errout_with_fd; + } + + /* mmap() the framebuffer. + * + * NOTE: In the FLAT build the frame buffer address returned by the + * FBIOGET_PLANEINFO IOCTL command will be the same as the framebuffer + * address. mmap(), however, is the preferred way to get the framebuffer + * address because in the KERNEL build, it will perform the necessary + * address mapping to make the memory accessible to the application. + */ + + g_pdc_fbstate.fbmem = mmap(NULL, pinfo.fblen, PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_FILE, g_pdc_fbstate.fd, 0); + if (g_pdc_fbstate.fbmem == MAP_FAILED) + { + PDC_LOG(("ERROR: ioctl(FBIOGET_PLANEINFO) failed: %d\n", errno)); + goto errout_with_fd; + } + + PDC_LOG(("Mapped FB: %p\n", g_pdc_fbstate.fbmem)); + + /* The the handle for the selected font */ + + g_pdc_fbstate.hfont = nxf_getfonthandle(PDCURSES_FONTID); + if (g_pdc_fbstate.hfont == NULL) + { + PDC_LOG(("ERROR: Failed to get font handle: %d\n", errno);) + goto errout_with_fd; + } + + /* Get information about the fontset */ + + fontset = nxf_getfontset(g_pdc_fbstate.hfont); + if (fontset == NULL) + { + PDC_LOG(("ERROR: Failed to get font handle: %d\n", errno);) + goto errout_with_font; + } + + PDC_LOG(("Fonset (ID=%d):\n", PDCURSES_FONTID)); + PDC_LOG((" mxheight: %u\n", fontset->mxheight)); + PDC_LOG((" mxwidth: %u\n", fontset->mxwidth)); + PDC_LOG((" mxbits: %u\n", fontset->mxbits)); + PDC_LOG((" spwidth: %u\n", fontset->spwidth)); + + g_pdc_fbstate.fheight = fontset->mxheight; + g_pdc_fbstate.fwidth = fontset->mxwidth; + + /* Calculate the drawable region */ + + SP->lines = g_pdc_fbstate.yres / g_pdc_fbstate.fheight; + SP->cols = g_pdc_fbstate.xres / g_pdc_fbstate.fwidth; + + g_pdc_fbstate.hoffset = (g_pdc_fbstate.yres - g_pdc_fbstate.fheight * SP->lines) / 2; + g_pdc_fbstate.hoffset = (g_pdc_fbstate.yres - g_pdc_fbstate.fheight * SP->lines) / 2; + + return OK; + +errout_with_font: + +errout_with_fd: + close(g_pdc_fbstate.fd); + g_pdc_fbstate.fd = -1; + +errout_with_sp: + free(SP); + SP = NULL; return ERR; }