Notcurses: blingful TUIs and character graphics

Notcurses: blingful TUIs and character graphics

What it is: a library facilitating complex TUIs on modern terminal emulators, supporting vivid colors, multimedia, threads, and Unicode to the maximum degree possible. Things can be done with Notcurses that simply can't be done with NCURSES. It is furthermore fast as shit. What it is not: a source-compatible X/Open Curses implementation, nor a replacement for NCURSES on existing systems.

setting the standard (hype video) birthed screaming into this world by nick black ([email protected])

for more information, see dankwiki and the man pages. in addition, there is Doxygen output. there is a mailing list which can be reached via [email protected]. i wrote a coherent guidebook, which is available for free download (or paperback purchase).

i've not yet added many documented examples, but src/poc/ and src/pocpp/ contain many small C and C++ programs respectively. notcurses-demo covers most of the functionality of Notcurses.

If you're running Notcurses applications in a Docker, please consult "Environment notes" below.

Packaging status

Linux FreeBSD Windows macOS Matrix Sponsor

Build Ubuntu macOS Windows

pypi_version crates.io

Introduction

Notcurses abandons the X/Open Curses API bundled as part of the Single UNIX Specification. For some necessary background, consult Thomas E. Dickey's superb and authoritative NCURSES FAQ. As such, Notcurses is not a drop-in Curses replacement.

Wherever possible, Notcurses makes use of the Terminfo library shipped with NCURSES, benefiting greatly from its portability and thoroughness.

Notcurses opens up advanced functionality for the interactive user on workstations, phones, laptops, and tablets, possibly at the expense of e.g. some industrial and retail terminals. Fundamentally, Curses assumes the minimum and allows you (with effort) to step up, whereas Notcurses assumes the maximum and steps down (by itself) when necessary. The latter approach probably breaks on some older hardware, but the former approach results in new software looking like old hardware.

Why use this non-standard library?

  • Thread safety, and efficient use in parallel programs, has been a design consideration from the beginning.

  • A more orderly surface than that codified by X/Open: Exported identifiers are prefixed to avoid common namespace collisions. Where reasonable, static inline header-only code is used. This facilitates compiler optimizations, and reduces loader time. Notcurses can be built without its multimedia functionality, requiring a significantly lesser set of dependencies.

  • All APIs natively support the Universal Character Set (Unicode). The nccell API is based around Unicode's Extended Grapheme Cluster concept.

  • Visual features including images, fonts, video, high-contrast text, sprites, and transparent regions. All APIs natively support 24-bit color, quantized down as necessary for the terminal.

  • It's Apache2-licensed in its entirety, as opposed to the drama in several acts that is the NCURSES license (the latter is summarized as "a restatement of MIT-X11").

Much of the above can be had with NCURSES, but they're not what NCURSES was designed for. On the other hand, if you're targeting industrial or critical applications, or wish to benefit from time-tested reliability and portability, you should by all means use that fine library.

Requirements

Minimum versions generally indicate the oldest version I've tested with; it may well be possible to use still older versions. Let me know of any successes!

  • (build) CMake 3.14.0+ and a C11 compiler
  • (OPTIONAL) (OpenImageIO, testing, C++ bindings): A C++17 compiler
  • (build+runtime) From NCURSES: terminfo 6.1+
  • (build+runtime) GNU libunistring 0.9.10+
  • (OPTIONAL) (build+runtime) GNU Readline 8.0+
  • (OPTIONAL) (build+runtime) From QR-Code-generator: libqrcodegen 1.5.0+
  • (OPTIONAL) (build+runtime) From FFmpeg: libswscale 5.0+, libavformat 57.0+, libavutil 56.0+
  • (OPTIONAL) (build+runtime) OpenImageIO 2.15.0+, requires C++
  • (OPTIONAL) (testing) Doctest 2.3.5+
  • (OPTIONAL) (documentation) pandoc 1.19.2+
  • (OPTIONAL) (python bindings): Python 3.7+, CFFI 1.13.2+, pypandoc 1.5+
  • (OPTIONAL) (rust bindings): rust 1.47.0+, bindgen 0.55.1+, pkg-config 0.3.18+, cty 0.2.1+
  • (runtime) Linux 5.3+, FreeBSD 11+, DragonFly BSD 5.9+, Windows Vista+, or macOS 11.4+

Here's more information on building and installation.

Included tools

Eight binaries are installed as part of Notcurses:

  • ncls: an ls that displays multimedia in the terminal
  • ncneofetch: a neofetch ripoff
  • ncplayer: renders visual media (images/videos)
  • nctetris: a tetris clone
  • notcurses-demo: some demonstration code
  • notcurses-info: detect and print terminal capabilities/diagnostics
  • notcurses-input: decode and print keypresses
  • notcurses-tester: unit testing

To run notcurses-demo from a checkout, provide the data directory via the -p argument. Demos requiring data files will otherwise abort. The base delay used in notcurses-demo can be changed with -d, accepting a floating-point multiplier. Values less than 1 will speed up the demo, while values greater than 1 will slow it down.

notcurses-tester likewise requires that data, populated with the necessary data files, be specified with -p. It can be run by itself, or via make test.

Documentation

With -DUSE_PANDOC=on (the default), a full set of man pages and XHTML will be built from doc/man. The following Markdown documentation is included directly:

If you (understandably) want to avoid the large Pandoc stack, but still enjoy manual page goodness, I publish a tarball with generated man/XHTML along with each release. Download it, and install the contents as you deem fit.

Environment notes

  • If your TERM variable is wrong, or that terminfo definition is out-of-date, you're going to have a very bad time. Use only TERM values appropriate for your terminal. If this variable is undefined, or Notcurses can't load the specified Terminfo entry, it will refuse to start, and you will not be going to space today.

  • Notcurses queries the terminal on startup, enabling some advanced features based on the determined terminal (and even version). Basic capabilities, however, are taken from Terminfo. So if you have, say, Kitty, but TERM=vt100, you're going to be able to draw RGBA bitmap graphics, but be able to use the alternate screen (despite the latter being supported by every Kitty version). So TERM and an up-to-date Terminfo database remain important.

  • Ensure your LANG environment variable is set to a UTF8-encoded locale, and that this locale has been generated. This usually means "[language]_[Countrycode].UTF-8", i.e. en_US.UTF-8. The first part (en_US) ought exist as a directory or symlink in /usr/share/locales. This usually requires editing /etc/locale.gen and running locale-gen. On Debian systems, this can be accomplished with dpkg-reconfigure locales, and enabling the desired locale. The default locale is stored somewhere like /etc/default/locale.

  • If your terminal has an option about default interpretation of "ambiguous-width characters" (this is actually a technical term from Unicode), ensure it is set to Wide, not narrow (if that doesn't work, ensure it is set to Narrow, heh).

  • If your terminal supports 3x8bit RGB color via setaf and setbf (most modern terminals), but exports neither the RGB nor Tc terminfo capability, you can export the COLORTERM environment variable as truecolor or 24bit. Note that some terminals accept a 24-bit specification, but map it down to fewer colors. RGB is unconditionally enabled whenever most modern terminals are identified.

Fonts

Glyph width, and indeed whether a glyph can be displayed at all, is dependent in part on the font configuration. Ideally, your font configuration has a glyph for every Unicode EGC, and each glyph's width matches up with the C library's wcswidth() result for the EGC. If this is not the case, you'll likely get blanks or � (U+FFFD, REPLACEMENT CHARACTER) for missing characters, and subsequent characters on the line may be misplaced.

It is worth knowing that several terminals draw the block characters directly, rather than loading them from a font. This is generally desirable. Quadrants and sextants are not the place to demonstrate your design virtuosity. To inspect your environment's rendering of drawing characters, run notcurses-info. The desired output ought look something like this:

notcurses-info can be used to check Unicode drawing

FAQs

If things break or seem otherwise lackluster, please consult the Environment Notes section! You need to have a correct TERM and LANG definition, and probably want COLORTERM.

The demo fails in the middle of intro. Check that your TERM value is correct for your terminal. intro does a palette fade, which is prone to breaking under incorrect TERM values. If you're not using xterm, your TERM should not be xterm!
Can I have Notcurses without this huge multimedia stack? Yes! Build with -DUSE_MULTIMEDIA=none.
Can I build this individual Notcurses program without aforementioned multimedia stack? Again yes! Use notcurses_core_init() or ncdirect_core_init() in place of notcurses_init()/ ncdirect_init(), and link with -lnotcurses-core. Your application will likely start a few milliseconds faster; more importantly, it will link against minimal Notcurses installations.
Notcurses looks like absolute crap in screen. screen doesn't support RGB colors (at least as of 4.08.00); if you have COLORTERM defined, you'll have a bad time. If you have a screen that was compiled with --enable-colors256, try exporting TERM=screen-256color as opposed to TERM=screen.
Notcurses looks like absolute crap in mosh. Yeah it sure does. I'm not yet sure what's up.
Why didn't you just render everything to Sixel? That's not a TUI; it's a slow and inflexible GUI. Many terminal emulators don't support Sixel. Sixel doesn't work well with mouse selection. Sixel has a limited color palette. With that said, both Sixel and the Kitty bitmap protocol are well-supported.
I'm not seeing NCKEY_RESIZE until I press some other key. You've almost certainly failed to mask SIGWINCH in some thread, and that thread is receiving the signal instead of the thread which called notcurses_getc_blocking(). As a result, the poll() is not interrupted. Call pthread_sigmask() before spawning any threads.
Using the C++ wrapper, how can I ensure that the NotCurses destructor is run when I return from main()? As noted in the C++ FAQ, wrap it in an artificial scope (this assumes your NotCurses is scoped to main()).
How do I hide a plane I want to make visible later? In order of least to most performant: move it offscreen using ncplane_move_yx(), move it underneath an opaque plane with ncplane_move_below(), or move it off-pile with ncplane_reparent().
Why isn't there an ncplane_box_yx()? Do you hate orthogonality, you dullard? ncplane_box() and friends already have far too many arguments, you monster.
Why doesn't Notcurses support 10- or 16-bit color? Notcurses supports 24 bits of color, spread across three eight-bit channels. You presumably mean 10-bit-per-channel color. I needed those six bits for other things. When terminals support it, Notcurses might support it.
The name is dumb. That's not a question?
I'm not finding qrcodegen on BSD, despite having installed graphics/qr-code-generator. Try cmake -DCMAKE_REQUIRED_INCLUDES=/usr/local/include. This is passed by bsd.port.mk.
Do you support musl? I try to! You'll need at least 1.20.
I only seem to blit in ASCII, and/or can't emit Unicode beyond ASCII in general. Your LANG environment variable is underdefined or incorrectly defined, or the necessary locale is not present on your machine (it is also possible that you explicitly supplied NCOPTION_INHIBIT_SETLOCALE, but never called setlocale(3), in which case don't do that).
I pretty much always need an ncplane when using a nccell. Why doesn't the latter hold a pointer to the former? Besides the massive redundancy this would entail, nccell needs to remain as small as possible, and you almost always have the ncplane handy if you've got a reference to a valid nccell anyway.
I ran notcurses-demo, but my table numbers don't match the Notcurses banner numbers, you charlatan. notcurses-demo renders several frames beyond the actual demos.
When my program exits, I don't have a cursor, or text is invisible, or colors are weird, ad nauseam. Ensure you're calling notcurses_stop()/ncdirect_stop() on all exit paths, including fatal signals (note that, by default, Notcurses installs handlers for most fatal signals to do exactly this).
How can I use Direct Mode in conjunction with libreadline? Pass NCDIRECT_OPTION_CBREAK to ncdirect_init(), and ensure you do not pass NCDIRECT_OPTION_NO_READLINE. If you'd like, set rl_readline_name and rl_attempted_completion_function prior to calling ncdirect_init(). With that said, consider using a Notcurses ncreader.
Will there ever be Java wrappers? I should hope not. If you want a Java solution, try Autumn Lamonte's Jexer.
Given that the glyph channel is initialized as transparent for a plane, shouldn't the foreground and background be initialized as transparent, also? Probably (they are instead by default initialized to opaque). This would change some of the most longstanding behavior of Notcurses, though, so it isn't happening.
Why does my right-to-left text appear left-to-right? Notcurses doesn't honor the BiDi state machine, and in fact forces left-to-right with BiDi codes. Likewise, ultra-wide glyphs will have interesting effects. ﷽!
I get linker errors when statically linking. Are you linking all necessary libraries? Use pkg-config --static --libs notcurses (or --libs notcurses-core) to discover them.
Can I avoid manually exporting COLORTERM=24bit everywhere? Sure. Add SendEnv COLORTERM to .ssh/config, and AcceptEnv COLORTERM to sshd_config on the remote server. Yes, this will probably require root on the remote server. Don't blame me, man; I didn't do it.
How about *arbitrary image manipulation here* functionality? I'm not going to beat ImageMagick et al. on image manipulation, but you can load an ncvisual from RGBA memory using ncvisual_from_rgba().
My program locks up during initialization. Notcurses interrogates the terminal. If the terminal doesn't reply to standard interrogations, file a Notcurses bug, send upstream a patch, or use a different terminal. No known terminal emulators exhibit this behavior.
Why no NCSTYLE_REVERSE? It would consume a precious bit. You can use ncchannels_reverse() to correctly invert fore- and background colors.
How do I mix Rendered and Direct mode? You really don't want to. You can stream a subprocess to a plane with the ncsubproc widget.
How can I clear the screen on startup in Rendered mode when not using the alternate screen? Call notcurses_refresh() after notcurses_init() returns successfully.
Why do the stats show more Linux framebuffer bitmap bytes written than total bytes written to the terminal? Linux framebuffer graphics aren't implemented via terminal writes, but instead writes directly into a memory map.

Useful links

“Our fine arts were developed, their types and uses were established, in times very different from the present, by men whose power of action upon things was insignificant in comparison with ours. But the amazing growth of our techniques, the adaptability and precision they have attained, the ideas and habits they are creating, make it a certainty that profound changes are impending in the ancient craft of the Beautiful.” —Paul Valéry

Comments
  • chafa sixel-encodes AllRGB images substantially faster than notcurses

    chafa sixel-encodes AllRGB images substantially faster than notcurses

    In the course of stunting on https://github.com/hpjansson/chafa/issues/27, I discovered that chafa 1.8.0 renders AllRGB/balloon.jpg in about half the time of ncplayer on my 3970X. Representative timings:

    [schwarzgerat](0) $ time chafa /media/chungus/images/allrgb/balloon.png  -f sixel > /dev/null
    
    real    0m0.420s
    user    0m0.744s
    sys     0m0.057s
    [schwarzgerat](0) $ 
    

    vs

    [schwarzgerat](0) $ time ~/src/dankamongmen/notcurses/build-3.0.5/ncplayer /media/chungus/images/allrgb/balloon.png  -sscale -k > /dev/null
    
    real    0m0.774s
    user    0m0.720s
    sys     0m0.053s
    [schwarzgerat](0) $ 
    

    in addition, the chafa output is slightly better -- look at the purple sections, and their borders with the blue sections to their right. we have some weird green pixels in there, unlike chafa.

    ncplayer:

    2022-01-23-150607_883x891_scrot

    chafa:

    2022-01-23-150616_880x922_scrot

    note that this is on amd64, where chafa AFAIK uses hand-coded SIMD. i'm not sure if that's true on other architectures, but who cares; i tolerate defeat on no platform. well, i suppose there's only one thing to do now.

    oh lawd you didnt bring a victim child

    THERE CAN BE ONLY ONE

  • mpv -vo sixel is far superior to ncplayer -bpixel

    mpv -vo sixel is far superior to ncplayer -bpixel

    @dnkl pointed this out in #1380, but it's worth its own issue. Get two xterms up, along with a recent mpv build featuring libsixel support. Run it alongside ncplayer -bpixel. mpv's superiority is obvious (we beat it with cell output, though). Get to this level of output, in both speed and quality.

  • split out libnotcurses-minimal without ffmpeg linkage

    split out libnotcurses-minimal without ffmpeg linkage

    @edmonds thinks it would be a good idea to split out a libnotcurses1 package sans ffmpeg linkage. I'm inclined to agree, though I think we differ a little on exactly how we'd like to see it done. This is not a blocker for uploading and sponsorship.

  • color divergence in sixel with fewer colors than color registers

    color divergence in sixel with fewer colors than color registers

    with quantanal improved in #2502, we're now seeing divergence on a more complex, but still simple, image:

    [schwarzgerat](0) $ ./quantanal ../data/chunli23.png
    analyzing ../data/chunli23.png...
     source pixels: 99x46
     rendered: 99x46 18216B
     control sequence: 3134 bytes (17.2%)
     00004554 pixels analyzed Δr 318498 Δg 3546 Δb 3600
     Colors: 17 vs 27
     4554px Δr 318498 (69.9) Δg 3546 (0.779) Δb 3600 (0.791)
     avg diff per pixel: 71.5
    done with ../data/chunli23.png.
    [schwarzgerat](0) $
    

    we're for some reason using 10 more colors, and missing by a wide 71.5 per. adding NOINTERPOLATION makes things worse:

    [schwarzgerat](0) $ ./quantanal ../data/chunli23.png
    analyzing ../data/chunli23.png...
     source pixels: 99x46
     rendered: 99x46 18216B
     control sequence: 3134 bytes (17.2%)
     00004554 pixels analyzed Δr 315107 Δg 5968 Δb 3489
     Colors: 17 vs 97
     4554px Δr 315107 (69.2) Δg 5968 (1.31) Δb 3489 (0.766)
     avg diff per pixel: 71.3
    done with ../data/chunli23.png.
    [schwarzgerat](0) $
    

    meanwhile, on another, we drastically reduce the number of colors:

    [schwarzgerat](0) $ ./quantanal ../data/worldmap.png
    analyzing ../data/worldmap.png...
     source pixels: 475x860
     rendered: 475x860 1634000B
     control sequence: 130695 bytes (7.998%)
     00408500 pixels analyzed Δr 828526 Δg 899641 Δb 877151
     Colors: 233 vs 43
     408500px Δr 828526 (2.03) Δg 899641 (2.2) Δb 877151 (2.15)
     avg diff per pixel: 6.38
    done with ../data/worldmap.png.
    [schwarzgerat](0) $
    
  • become a thing on windows

    become a thing on windows

    In a Kantian sense, it would seem a good thing if notcurses worked on windows, for whatever definition of works that means. I very much doubt that I will ever undertake this work, but if some brave soul wishes to take a stab at it, or report problems, or whatever, here's a bug in which you might do that.

  • CLI mode always involves at least two rows

    CLI mode always involves at least two rows

    Run e.g. grid or any other CLI-style program that has no text output. There will be a blank line before the new prompt. Running e.g. true or other such tools results in no such blank line, and we oughtn't either.

  • Why ncplane_putegc() needs termination character?

    Why ncplane_putegc() needs termination character?

  • `NCOPTION_SUPPRESS_BANNERS` breaks default colors in a non standard plane

    `NCOPTION_SUPPRESS_BANNERS` breaks default colors in a non standard plane

    I have a status line in my application that can be used to display an overview of all keyboard shortcuts. The status line has a default background color and is in a separate plane. Initially, the status line is drawn correctly with the right background and foreground color. When the user presses '?', the status line will print some application shortcut descriptions.

    I notice that when I suppress notcurses banners using NCOPTION_SUPPRESS_BANNER, when the help is displayed in the status line, the text is not printed with the background color for the status line plane:

    Initial view (the gray line is the status bar of the application, the rest is tmux):

    initial

    After pressing '?' without NCOPTION_SUPPRESS_BANNER:

    good

    After pressing '?' with NCOPTION_SUPPRESS_BANNER:

    bad

    The following program reproduces the problem:

    #include <locale.h>
    #include <notcurses/notcurses.h>
    #include <stdlib.h>
    
    static struct ncplane *make_status_line_plane(struct ncplane *std_plane) {
      struct ncplane_options opts = {0};
      opts.rows = 1;
      opts.cols = ncplane_dim_x(std_plane);
      opts.y = ncplane_dim_y(std_plane) - 1;
      opts.x = 0;
    
      nccell c = CELL_CHAR_INITIALIZER(' ');
      cell_set_bg_rgb8(&c, 0x20, 0x20, 0x20);
    
      struct ncplane *status_line_plane = ncplane_create(std_plane, &opts);
      ncplane_set_base_cell(status_line_plane, &c);
      return status_line_plane;
    }
    
    static void print_status_line(struct ncplane *plane) {
      ncplane_putstr_aligned(plane, 0, NCALIGN_LEFT, " ?: help");
    }
    
    static void print_help(struct ncplane *plane) {
      const int width = ncplane_dim_x(plane);
      ncplane_erase(plane);
      ncplane_putstr_aligned(
          plane, 0, NCALIGN_LEFT,
          " j/k: scroll up/down   C-B/C-F: page up/down   q: quit");
      ncplane_putstr_aligned(plane, 0, NCALIGN_RIGHT,
                             "press any key to close help ");
    }
    
    int main(int argc, char **argv) {
      setlocale(LC_ALL, "");
    
      notcurses_options opts = {0};
      opts.flags = NCOPTION_SUPPRESS_BANNERS;
    
      struct notcurses *nc;
      if ((nc = notcurses_core_init(&opts, NULL)) == NULL) {
        return EXIT_FAILURE;
      }
    
      struct ncplane *std_plane = notcurses_stdplane(nc);
      struct ncplane *status_line_plane = make_status_line_plane(std_plane);
    
      ncplane_move_top(status_line_plane);
    
      struct ncinput input = {0};
      bool quit = false;
      while (!quit) {
        print_status_line(status_line_plane);
        notcurses_render(nc);
        notcurses_getc_blocking(nc, &input);
        switch (input.id) {
        case '?':
          print_help(status_line_plane);
          notcurses_render(nc);
          notcurses_getc_blocking(nc, &input);
          ncplane_erase(status_line_plane);
          break;
        case 'q':
          quit = true;
          break;
        }
      }
    
      notcurses_stop(nc);
    }
    

    Is this an issue in the program above, or maybe a bug in notcurses itself?

    I am using notcurses 2.1.7. My terminal is st 0.8.4. Ouput from export | egrep 'LANG|LC_CTYPE|TERM':

    LANG=en_US.UTF-8
    TERM=tmux-256color
    TERMINAL=st
    TERMINFO=/home/ton/.local/share/terminfo
    
  • unite our two control sequence automata

    unite our two control sequence automata

    We have two automata we traverse to handle control escapes -- the one handled by pump_control_read(), and the special key trie. as a result, we have two distinct control loops, and two distinct states. this last is horrible, as there's no well-defined map of state changes effected by one on the other.

    unite these two automata. given that special keys require a dynamic state machine (it's prepared based on terminfo data), a wholly explicit controlflow-based automaton (like that used in pump_control_read()) won't work. we need a dataflow-based one, as used by our trie traversal.

    so we'll need add some special node types to our trie, basically the same we have from the other automaton:

    • accumulate a number
    • accumulate a string
    • accumulate a hex-encoded string, which is just a special case of either of the previous 2 ...and that's it, i think? pretty easy. let's do it up right
  • handle terminal interrogation failure better

    handle terminal interrogation failure better

    Currently, if we interrogate a terminal, and don't get a response, the program will simply hang. Hence the requirement that the user explicitly call some function (e.g. notcurses_check_pixel_support()) before we begin interrogation.

    I hate this so fucking much. I have no idea whether user input can break up the terminal response, but it wouldn't surprise me at all (and if it doesn't break the response, we'll at best lose said input). Hate hate hate hate hate.

    I've been unwilling to put in a timeout, because on a loaded system, a slow reply is totally normal, and what timeout would we use, and even worse would be pushing that timeout question to the user, because they know nothing. I stand by this decision, because I am a dinosaur and a curmudgeon and everyone's too busy these days. Let the computer cogitate, if that's what it needs to do.

    I do think, however, that we need at least print a diagnostic after a certain time goes by without a response, so the user isn't just left with no idea what's up. I think this can be dumped to stderr; it'll be jarring and disrupt any drawn screen, but hey, you've been sitting around for five (or whatver) stimulus-free seconds already, and in all likelihood you'll be sitting there until time ends or the power fails.

    So yeah, make a concession to reality, and after say 5 seconds without a response from the terminal, print a diagnostic to stderr about "N seconds without a response from the terminal....". Maybe include the TERM value in this output for the inevitable bug reports.

    Better yet would be a method to break user input up from terminal responses, but I doubt that this is possible =[. Maybe we ought take unrecognized input and queue it up as user input, but then we're just forwards-incompatible with new, wacky returns from tomorrow's terminals.

    Fuck the world, save yourself.

  • DECSDM is a poorly-understood hellscape

    DECSDM is a poorly-understood hellscape

    I haven't tested with a specific version of notcurses, but I've seen in the code that you set private mode 80 when you initialize sixel: https://github.com/dankamongmen/notcurses/blob/3dbb3c149d2dafa57f51bcaa96a54176a4cd66d1/src/lib/sixel.c#L871

    There is some confusion as to whether DECSDM is intended to enable sixel scrolling or disable it, and around half the terminals I've tested have implemented it one way, and half the other. On terminals that interpret mode 80 as a request to to disable sixel scrolling, your sixel images are going to be rendered in the wrong place.

    For the record, I think you are using it is the wrong way, but considering how terminals are currently split on this issue, there really isn't a right way. The best course of action is to leave that mode alone. Every terminal I've tested does at least have sixel scrolling enabled by default, so unless you actually need to disable scrolling, there should be no reason to change the mode.

  • after installing notcurses on windows 10 wsl2 ubuntu 18 lts... blank output

    after installing notcurses on windows 10 wsl2 ubuntu 18 lts... blank output

    I follow installation instructions... when running the tests it freezes up on test one... I am able to run make install and make demo... I get a blank output until i enter cmd+D on my keyboard and am put back into my terminal... any advice would be appreciated.

    this is the output of the test

    Running with LANG=C.UTF-8
    Running with TERM=xterm-256color```
    
    THANKS!
  • pkt_duration has been deprecated in ffmpeg

    pkt_duration has been deprecated in ffmpeg

    Attempting to build against recent (git checkout) ffmpeg hits:

    [ 20%] Building C object CMakeFiles/notcurses.dir/src/media/ffmpeg.c.o
    /home/dank/src/dankamongmen/notcurses/src/media/ffmpeg.c: In function ‘ffmpeg_stream’:
    /home/dank/src/dankamongmen/notcurses/src/media/ffmpeg.c:523:5: warning: ‘pkt_duration’ is deprecated [-Wdeprecated-declarations]
      523 |     uint64_t duration = ncv->details->frame->pkt_duration * tbase * NANOSECS_IN_SEC;
          |     ^~~~~~~~
    In file included from /home/dank/src/dankamongmen/notcurses/src/media/ffmpeg.c:4:
    /usr/local/include/libavutil/frame.h:617:13: note: declared here
      617 |     int64_t pkt_duration;
          |             ^~~~~~~~~~~~
    
  • None of the required 'tinfo>=6.1;ncursesw>=6.1' found

    None of the required 'tinfo>=6.1;ncursesw>=6.1' found

    Environment:

    • OS: Centos 7.9
    • notcurses version: 3.0.8
    • GCC: 4.8.5

    compile from source code by issuing the command cmake ../ -DUSE_GPM=on -DUSE_QRCODEGEN=on -DBUILD_TESTING=off -DUSE_DOCTEST=off -DUSE_MULTIMEDIA=none, then throw errors as below:

    -- Checking for one of the modules 'tinfo>=6.1;ncursesw>=6.1'
    CMake Error at /usr/local/share/cmake-3.23/Modules/FindPkgConfig.cmake:890 (message):
      None of the required 'tinfo>=6.1;ncursesw>=6.1' found
    Call Stack (most recent call first):
      CMakeLists.txt:104 (pkg_search_module)
    

    Besides, I have built and installed the latest ncurses library with version 6.3, and I have did lots of google search for tinfo, but no any clues found, so how to install tinfo with version required? and I found the library file 【/usr/lib/libncursesw.so.6.3】already exists, so why it still report that ncursesw >= 6.1 ? any help will be appreciated.

  • Cannot build library with OpenImageIO multimedia engine using MinGW 64

    Cannot build library with OpenImageIO multimedia engine using MinGW 64

    While trying to build libs using mingw, i get the error below. I used following cmake options: USE_DOCTEST=off USE_PANDOC=off BUILD_EXECUTABLES=off USE_MULTIMEDIA=oiio. Using ffmpeg instead of OpenImageIO helps, but perfomance is bad and the demo breaks after the penguin scene.

    [109/112] Linking CXX shared library libnotcurses.dll
    FAILED: libnotcurses.dll libnotcurses.dll.a
    cmd.exe /C "cd . && C:\msys64\ucrt64\bin\c++.exe -O2 -g -DNDEBUG   -shared -o libnotcurses.dll -Wl,--out-implib,libnotcurses.dll.a -Wl,--major-image-version,3,--minor-image-version,0 CMakeFiles/notcurses.dir/src/media/ffmpeg.c.obj CMakeFiles/notcurses.dir/src/media/none.c.obj CMakeFiles/notcurses.dir/src/media/oiio-indep.c.obj CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj CMakeFiles/notcurses.dir/src/media/shim.c.obj CMakeFiles/notcurses.dir/src/compat/compat.c.obj -L/usr/local/lib libnotcurses-core.dll.a  -lOpenImageIO  -lwsock32  -lws2_32  -lsecur32  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> >::size() const':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_vector.h:988: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValueaSERKS0_'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `void std::_Destroy_aux<false>::__destroy<__gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > > >(__gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, __gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >)':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `OpenImageIO_v2_4_5::ParamValue* std::__copy_move<false, false, std::random_access_iterator_tag>::__copy_m<OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*>(OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*)':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_algobase.h:383: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValueaSERKS0_'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `OpenImageIO_v2_4_5::ParamValue* std::__do_uninit_copy<OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*>(OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*)':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_uninitialized.h:119: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue12init_noclearENS_7ustringENS_8TypeDescEiNS0_6InterpEPKvNS0_4CopyENS0_11FromUstringE'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `OpenImageIO_v2_4_5::ParamValue* std::__do_uninit_copy<__gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue const*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, OpenImageIO_v2_4_5::ParamValue*>(__gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue const*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, __gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue const*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, OpenImageIO_v2_4_5::ParamValue*)':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_uninitialized.h:116: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue12init_noclearENS_7ustringENS_8TypeDescEiNS0_6InterpEPKvNS0_4CopyENS0_11FromUstringE'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `void std::_Destroy_aux<false>::__destroy<OpenImageIO_v2_4_5::ParamValue*>(OpenImageIO_v2_4_5::ParamValue*, OpenImageIO_v2_4_5::ParamValue*)':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv'
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj:C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_construct.h:162: more undefined references to `__imp__ZN18OpenImageIO_v2_4_510ParamValue11clear_valueEv' follow
    C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles/notcurses.dir/src/media/oiio.cpp.obj: in function `OpenImageIO_v2_4_5::ParamValue* std::uninitialized_copy<__gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue const*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, OpenImageIO_v2_4_5::ParamValue*>(__gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue const*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, __gnu_cxx::__normal_iterator<OpenImageIO_v2_4_5::ParamValue const*, std::vector<OpenImageIO_v2_4_5::ParamValue, std::allocator<OpenImageIO_v2_4_5::ParamValue> > >, OpenImageIO_v2_4_5::ParamValue*)':
    C:/msys64/ucrt64/include/c++/12.2.0/bits/stl_uninitialized.h:119: undefined reference to `__imp__ZN18OpenImageIO_v2_4_510ParamValue12init_noclearENS_7ustringENS_8TypeDescEiNS0_6InterpEPKvNS0_4CopyENS0_11FromUstringE'
    collect2.exe: error: ld returned 1 exit status
    [110/112] Building CXX object CMakeFiles/notcurses-static.dir/src/media/oiio.cpp.obj
    ninja: build stopped: subcommand failed.
    
  • pthread_cancel()  is bad.

    pthread_cancel() is bad.

    The presence of pthread_cancel() hinders portability on arm-based platforms. We need to look for less problematic alternatives to pthread_cancel(). Look
    https://github.com/termux/termux-packages/issues/8860 https://github.com/termux/termux-packages/pull/11626

Free open-source modern C++17 / C++20 framework to create console, forms (GUI like WinForms) and unit test applications on Microsoft Windows, Apple macOS and Linux.
Free open-source modern C++17 / C++20 framework to create console, forms (GUI like WinForms) and unit test applications on Microsoft Windows, Apple macOS and Linux.

xtd Modern C++17/20 framework to create console (CLI), forms (GUI like WinForms) and tunit (unit tests like Microsoft Unit Testing Framework) applicat

Jan 4, 2023
Latte is a dock based on plasma frameworks that provides an elegant and intuitive experience for your tasks and plasmoids.
Latte is a dock based on plasma frameworks that provides an elegant and intuitive experience for your tasks and plasmoids.

Latte is a dock based on plasma frameworks that provides an elegant and intuitive experience for your tasks and plasmoids. It animates its contents by using parabolic zoom effect and trys to be there only when it is needed.

Jan 7, 2023
Build performant, native and cross-platform desktop applications with Node.js and CSS like styling. 🚀
Build performant, native and cross-platform desktop applications with Node.js and CSS like styling. 🚀

NodeGui Build performant, native and cross-platform desktop applications with Node.js and CSS like styling. ?? NodeGUI is powered by Qt5 ?? which make

Dec 30, 2022
C, C++ headers and C# classes for icon fonts: Font Awesome, Fork Awesome, Material Design, Kenney game icons and Fontaudio

C, C++ headers and C# classes for icon fonts: Font Awesome, Fork Awesome, Material Design, Kenney game icons and Fontaudio

Jan 5, 2023
Purely native C++ cross-platform GUI framework for Android and iOS development. https://www.boden.io
Purely native C++ cross-platform GUI framework for Android and iOS development. https://www.boden.io

BODEN CROSS-PLATFORM FRAMEWORK Build purely native cross-platform experiences with Boden Website ⬡ Getting Started ⬡ API Reference ⬡ Guides ⬡ Twitter

Dec 27, 2022
GPU Accelerated C++ User Interface, with WYSIWYG developing tools, XML supports, built-in data binding and MVVM features.

GacUI GPU Accelerated C++ User Interface, with WYSIWYG developing tools, XML supports, built-in data binding and MVVM features. Read the LICENSE first

Jan 7, 2023
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

libui: a portable GUI library for C This README is being written. Status It has come to my attention that I have not been particularly clear about how

Jan 2, 2023
Minimalistic C++/Python GUI library for OpenGL, GLES2/3, Metal, and WebAssembly/WebGL
Minimalistic C++/Python GUI library for OpenGL, GLES2/3, Metal, and WebAssembly/WebGL

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3+, GLES 2/3, and Metal. It supports automatic layout generation, stateful

Dec 28, 2022
A barebones single-header GUI library for Win32 and X11.
A barebones single-header GUI library for Win32 and X11.

luigi A barebones single-header GUI library for Win32 and X11. Building example Windows Update luigi_example.c to #define UI_WINDOWS at the top of the

Dec 30, 2022
An efficient graphical Minecraft seed finder and map viewer.

Cubiomes Viewer provides a graphical interface for the efficient and flexible seed-finding utilities provided by cubiomes and a map viewer for the Minecraft biomes and structure generation.

Jan 7, 2023
DeskGap is a framework for building cross-platform desktop apps with web technologies (JavaScript, HTML and CSS).
DeskGap is a framework for building cross-platform desktop apps with web technologies (JavaScript, HTML and CSS).

A cross-platform desktop app framework based on Node.js and the system webview

Jan 4, 2023
[WIP] Demo of a minimal but functional Dawn-based WebGPU client and server

dawn client-server example The goal of this demo is to create a minimal but functional Dawn-based WebGPU client and server with the following traits:

Sep 19, 2022
A minimalist andf platform-agnostic application layer for writing graphical applications, with a strong emphasis on simplicity and ease of use.
A minimalist andf platform-agnostic application layer for writing graphical applications, with a strong emphasis on simplicity and ease of use.

SlimApp A minimalist(*) and platform-agnostic application layer for writing graphical applications. Available as either a single header file or a dire

Dec 18, 2022
Nvui: A NeoVim GUI written in C++ and Qt
Nvui: A NeoVim GUI written in C++ and Qt

Nvui: A NeoVim GUI written in C++ and Qt

Jan 7, 2023
Podman System Tray Icon for controlling `podman machine` and `podman system connection`.
Podman System Tray Icon for controlling `podman machine` and `podman system connection`.

Podman System Tray Icon Running Open in Qt Creator GUI: qtcreator systray.pro Or on the command line: $ qmake

Dec 11, 2021
super duper simple gui for C, wrapping imgui and stb

super duper simle gui for C, wrapping imgui and stb You can use it as a static library with cmake. See the example directory for a complete example. E

May 19, 2022
U++ is a C++ cross-platform rapid application development framework focused on programmer's productivity. It includes a set of libraries (GUI, SQL, Network etc.), and integrated development environment (TheIDE).
U++ is a C++ cross-platform rapid application development framework focused on programmer's productivity. It includes a set of libraries (GUI, SQL, Network etc.), and integrated development environment (TheIDE).

Ultimate++ Ultimate++ is a C++ cross-platform rapid application development framework focused on programmers productivity. It includes a set of librar

Jan 8, 2023
raygui is a simple and easy-to-use immediate-mode-gui library.
raygui is a simple and easy-to-use immediate-mode-gui library.

raygui is a simple and easy-to-use immediate-mode-gui library.

Dec 30, 2022
A wallpaper changer using Wallhaven api. Written with C++/CLR, only 0.5 MB and have a GUI.
A wallpaper changer using Wallhaven api. Written with C++/CLR, only 0.5 MB and have a GUI.

WHaven Wallpaper WHaven Wallpaper is a desktop wallpaper change program for change your wallpapers directly from wallhaven. Features You have a search

Aug 1, 2022