apps/graphics/pdcurs34/nuttx: Add framebuffer initialization logic.

This commit is contained in:
Gregory Nutt 2017-11-18 15:27:12 -06:00
parent e33fe59cab
commit 65555542e5
7 changed files with 281 additions and 27 deletions

View file

@ -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)).

View file

@ -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

View file

@ -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

View file

@ -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
****************************************************************************/

View file

@ -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
****************************************************************************/

View file

@ -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 */

View file

@ -37,8 +37,27 @@
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#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;
}