---
name: "notcurses_direct"
section: "3"
platform: "linux"
package: "notcurses"
version: "3.0.17-3"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/notcurses_direct"
---

# notcurses\_direct(3)

the Direct Mode API

## NAME

notcurses\_direct - the Direct Mode API

## SYNOPSIS

-

  ```
  #include <notcurses/direct.h>
  #define NCDIRECT_OPTION_INHIBIT_SETLOCALE   0x0001ull
  #define NCDIRECT_OPTION_INHIBIT_CBREAK      0x0002ull
  #define NCDIRECT_OPTION_NO_QUIT_SIGHANDLERS 0x0008ull
  #define NCDIRECT_OPTION_VERBOSE             0x0010ull
  #define NCDIRECT_OPTION_VERY_VERBOSE        0x0020ull
  ```

**struct ncdirect\* ncdirect\_init(const char\*** *termtype***, FILE\*** *fp***, uint64\_t** *flags***);**

**unsigned ncdirect\_palette\_size(const struct ncdirect\*** *nc***);**

**int ncdirect\_set\_bg\_rgb8(struct ncdirect\*** *nc***,** **unsigned** *r***, unsigned** *g***, unsigned** *b***);**

**int ncdirect\_set\_fg\_rgb8(struct ncdirect\*** *nc***,** **unsigned** *r***, unsigned** *g***, unsigned** *b***);**

**int ncdirect\_set\_fg\_rgb(struct ncdirect\*** *nc***,** **unsigned** *rgb***);**

**int ncdirect\_set\_bg\_rgb(struct ncdirect\*** *nc***,** **unsigned** *rgb***);**

**int ncdirect\_set\_fg\_default(struct ncdirect\*** *nc***);**

**int ncdirect\_set\_bg\_default(struct ncdirect\*** *nc***);**

**int ncdirect\_set\_fg\_palindex(struct ncdirect\*** *nc***, int** *pidx***);**

**int ncdirect\_set\_bg\_palindex(struct ncdirect\*** *nc***, int** *pidx***);**

**unsigned ncdirect\_dim\_x(const struct ncdirect\*** *nc***);**

**unsigned ncdirect\_dim\_y(const struct ncdirect\*** *nc***);**

**unsigned ncdirect\_supported\_styles(const struct ncdirect\*** *nc***);**

**int ncdirect\_styles\_set(struct ncdirect\*** *n***,** **unsigned** *stylebits***);**

**int ncdirect\_styles\_on(struct ncdirect\*** *n***,** **unsigned** *stylebits***);**

**int ncdirect\_styles\_off(struct ncdirect\*** *n***,** **unsigned** *stylebits***);**

**unsigned ncdirect\_styles(struct ncdirect\*** *n***);**

**int ncdirect\_clear(struct ncdirect\*** *nc***)**

**int ncdirect\_stop(struct ncdirect\*** *nc***);**

**int ncdirect\_cursor\_move\_yx(struct ncdirect\*** *n***,** **int** *y***, int** *x***);**

**int ncdirect\_cursor\_yx(struct ncdirect\*** *n***,** **unsigned\*** *y***, unsigned\*** *x***);**

**int ncdirect\_cursor\_enable(struct ncdirect\*** *nc***);**

**int ncdirect\_cursor\_disable(struct ncdirect\*** *nc***);**

**int ncdirect\_cursor\_up(struct ncdirect\*** *nc***, int** *num***);**

**int ncdirect\_cursor\_left(struct ncdirect\*** *nc***,** **int** *num***);**

**int ncdirect\_cursor\_right(struct ncdirect\*** *nc***,** **int** *num***);**

**int ncdirect\_cursor\_down(struct ncdirect\*** *nc***,** **int** *num***);**

**int ncdirect\_putstr(struct ncdirect\*** *nc***,** **uint64\_t** *channels***, const char\*** *utf8***);**

**int ncdirect\_putegc(struct ncdirect\*** *nc***,** **uint64\_t** *channels***, const char\*** *utf8***, int\*** *sbytes***);**

**int ncdirect\_printf\_aligned(struct ncdirect\*** *n***,** **int** *y***, ncalign\_e** *align***, const** **char\*** *fmt***,** *...***);**

**const char\* ncdirect\_detected\_terminal(const struct ncdirect\*** *n***);**

**int ncdirect\_hline\_interp(struct ncdirect\*** *n***,** **const char\*** *egc***, unsigned** *len***,** **uint64\_t** *h1***, uint64\_t** *h2***);**

**int ncdirect\_vline\_interp(struct ncdirect\*** *n***,** **const char\*** *egc***, unsigned** *len***,** **uint64\_t** *h1***, uint64\_t** *h2***);**

**int ncdirect\_box(struct ncdirect\*** *n***, uint64\_t** *ul***, uint64\_t** *ur***, uint64\_t** *ll***, uint64\_t** *lr***, const wchar\_t\*** *wchars***, int** *ylen***, int** *xlen***, unsigned** *ctlword***);**

**int ncdirect\_rounded\_box(struct ncdirect\*** *n***,** **uint64\_t** *ul***, uint64\_t** *ur***,** **uint64\_t** *ll***, uint64\_t** *lr***, int** *ylen***, int** *xlen***, unsigned** *ctlword***);**

**int ncdirect\_double\_box(struct ncdirect\*** *n***,** **uint64\_t** *ul***, uint64\_t** *ur***,** **uint64\_t** *ll***, uint64\_t** *lr***, int** *ylen***, int** *xlen***, unsigned** *ctlword***);**

**ncdirectv\* ncdirect\_render\_frame(struct ncdirect\*** *n***, const char\*** *filename***,** **ncblitter\_e** *blitter***, ncscale\_e** *scale***, int** *maxy***, int** *maxx***);**

**char\* ncdirect\_readline(struct ncdirect\*** *n***,** **const char\*** *prompt***);**

**bool ncdirect\_cantruecolor(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canchangecolor(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canfade(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canopen\_images(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canopen\_videos(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canutf8(const struct ncdirect\*** *nc***);**

**int ncdirect\_check\_pixel\_support(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canhalfblock(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canquadrant(const struct ncdirect\*** *nc***);**

**bool ncdirect\_cansextant(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canoctant(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canbraille(const struct ncdirect\*** *nc***);**

**bool ncdirect\_canget\_cursor(const struct ncdirect\*** *nc***);**

**uint32\_t ncdirect\_get(struct ncdirect\*** *n***, const** **struct timespec\*** *absdl***, ncinput\*** *ni***);**

-

  ```
  typedef struct ncvgeom {
    int pixy, pixx;     // true pixel geometry of ncvisual data
    int cdimy, cdimx;   // terminal cell geometry when this was calculated
    int rpixy, rpixx;   // rendered pixel geometry
    int rcelly, rcellx; // rendered cell geometry
    int scaley, scalex; // pixels per filled cell
    // only defined for NCBLIT_PIXEL
    int maxpixely, maxpixelx;
  } ncvgeom;
  ```

**int ncdirect\_render\_image(struct ncdirect\*** *n***,** **const char\*** *filename***, ncblitter\_e** *blitter***, ncscale\_e** *scale***);**

**int ncdirect\_raster\_frame(struct ncdirect\*** *n***,** **ncdirectv\*** *ncdv***, ncalign\_e** *align***);**

**int ncdirect\_stream(struct ncdirect\*** *n***, const** **char\*** *filename***, ncstreamcb** *streamer***, struct ncvisual\_options\*** *vopts***, void\*** *curry***);**

**int ncdirect\_raster\_frame(struct ncdirect\*** *n***,** **ncdirectv\*** *ncdv***, ncalign\_e** *align***);**

**struct ncdirectf\* ncdirectf\_from\_file(struct ncdirect\*** *n***, const char\*** *filename***);**\*

**void ncdirectf\_free(struct ncdirectf\*** *frame***);**

**ncdirectv\* ncdirectf\_render(struct ncdirect\*** *n***,** **struct ncdirectf\*** *frame***, const struct** **ncvisual\_options** *vopts***);**

**int ncdirectf\_geom(struct ncdirect\*** *n***, struct** **ncdirectf\*** *frame***, const struct ncvisual\_options** *vopts***, ncvgeom\*** *geom***);**

## DESCRIPTION

**ncdirect\_init** prepares the **FILE** provided as **fp** for colorizing and styling. On success, a pointer to a valid **struct ncdirect** is returned. **NULL** is returned on failure. Before the process exits, **ncdirect\_stop** should be called to reset the terminal and free up resources. **ncdirect\_init** places the terminal into "cbreak" (also known as "rare") mode, disabling line-buffering and echo of input. **ncdirect\_stop** restores the terminal state as it was when the corresponding **ncdirect\_init** call was made. A process can have only one context active at once.

The following flags are defined:

- •

  **NCDIRECT\_OPTION\_INHIBIT\_SETLOCALE**: Unless this flag is set, **ncdirect\_init** will call **setlocale(LC\_ALL, NULL)**. If the result is either "**C**" or "**POSIX**", it will print a diagnostic to **stderr**, and then call **setlocale(LC\_ALL, "").** This will attempt to set the locale based off the **LANG** environment variable. Your program should call **[setlocale(3)](/setlocale/3.md)** itself, usually as one of the first lines.

- •

  **NCDIRECT\_OPTION\_INHIBIT\_CBREAK**: Unless this flag is set, **ncdirect\_init** will place the terminal into cbreak mode (i.e. disabling echo and line buffering; see **[tcgetattr(3)](/tcgetattr/3.md)**).

- •

  **NCDIRECT\_OPTION\_DRAIN\_INPUT**: Standard input may be freely discarded. If you do not intend to process input, pass this flag. Otherwise, input can buffer up, eventually preventing Notcurses from processing terminal messages. It will furthermore avoid wasting time processing useless input.

- •

  **NCDIRECT\_OPTION\_NO\_QUIT\_SIGHANDLERS**: A signal handler will usually be installed for **SIGABRT**, **SIGBUS**, **SIGFPE**, **SIGILL**, **SIGINT**, **SIGQUIT**, **SIGSEGV**, and **SIGTERM**, cleaning up the terminal on such exceptions. With this flag, the handler will not be installed.

- •

  **NCDIRECT\_OPTION\_VERBOSE**: Enable diagnostics to **stderr** at the level of **NCLOGLEVEL\_WARNING**.

- •

  **NCDIRECT\_OPTION\_VERY\_VERBOSE**: Enable all diagnostics (equivalent to **NCLOGLEVEL\_TRACE**). Implies **NCDIRECT\_OPTION\_VERBOSE**.

The loglevel can also be set externally using the **NOTCURSES\_LOGLEVEL** environment variable. See **[notcurses\_init(3)](/notcurses_init/3.md)** for more information.

An appropriate **[terminfo(5)](/terminfo/5.md)** entry must exist for the terminal. This entry is usually selected using the value of the **TERM** environment variable (see **[getenv(3)](/getenv/3.md)**), but a non-**NULL** value for **termtype** will override this. An invalid terminfo specification can lead to reduced performance, reduced display capabilities, and/or display errors. notcurses natively targets 24bpp/8bpc RGB color, and it is thus desirable to use a terminal with the **rgb** capability (e.g. xterm's **xterm-direct**).

**ncdirect\_dim\_x** returns the current number of columns, and **ncdirect\_dim\_y** the current number of rows.

**ncdirect\_clear** clears the screen using a control code if one exists in terminfo. Otherwise, it prints successive newlines to scroll everything off.

**ncdirect\_cursor\_move\_yx** moves the cursor to the specified coordinate. -1 can be specified for either **y** or **x** to leave that axis unchanged.

**ncdirect\_enable\_cursor** and **ncdirect\_disable\_cursor** always flush the output stream, taking effect immediately.

**ncdirect\_cursor\_up** and friends all move relative to the current position. Attempting to e.g. move up while on the top row will return 0, but have no effect.

**ncdirect\_readline** reads a (heap-allocated) line of arbitrary length, supporting some libreadline-style line-editing controls. **NCDIRECT\_OPTION\_INHIBIT\_CBREAK** should not be used if you intend to use **ncdirect\_readline**; if used, line-editing keybindings cannot be implemented. Input will be echoed whether this option is used or not.

**ncdirect\_check\_pixel\_support** must be called (and successfully return) before **NCBLIT\_PIXEL** can be used to render images; see **[notcurses\_visual(3)](/notcurses_visual/3.md)** for more details.

When rendering an image, ***maxy*** and ***maxx*** specify a maximum number of (cell) rows and columns to use, respectively. Passing 0 means "use as much space as is necessary". It is an error to pass a negative number for either.

## RETURN VALUES

**ncdirect\_init** returns **NULL** on failure. Otherwise, the return value points to a valid **struct ncdirect**, which can be used until it is provided to **ncdirect\_stop**.

**ncdirect\_printf\_aligned** returns the number of bytes written on success. On failure, it returns some negative number.

**ncdirect\_putstr** returns a nonnegative number on success, and **EOF** on failure.

**ncdirect\_putegc** returns the number of columns consumed on success, or -1 on failure. If ***sbytes*** is not **NULL**, the number of bytes consumed will be written to it.

**ncdirect\_check\_pixel\_support** returns -1 on error, 0 if there is no pixel support, and 1 if pixel support is successfully detected.

**ncdirect\_styles** returns the current styling, a bitmask over the various **NCSTYLE\_** constants.

All other functions return 0 on success, and non-zero on error.

## NOTES

You are recommended to accept **-v** and **-vv** as command-line options, mapping them to **NCDIRECT\_OPTION\_VERBOSE** and **NCDIRECT\_OPTION\_VERY\_VERBOSE** respectively.

## SEE ALSO

**[getenv(3)](/getenv/3.md)**, **[notcurses(3)](/notcurses/3.md)**, **[notcurses\_init(3)](/notcurses_init/3.md)**, **[notcurses\_plane(3)](/notcurses_plane/3.md)**, **[notcurses\_visual(3)](/notcurses_visual/3.md)**, **[terminfo(5)](/terminfo/5.md)**, **[termios(3)](/termios/3.md)**

## AUTHORS

nick black ⟨nickblack@linux.com⟩\\c.
