Ada Binding to "Wide" ncurses

If you're not interested in Text User Interfaces, feel free to skip this post.

Like I mentioned in a previous post, I think TUIs make a lot of sense for "admin interfaces" for cloud and on-prem systems. It's also possible their use will be forced for end-users once again if RAM prices keep going up, but we'll see. Its technical merits are arguable, but the curses library for TUIs is part of the Single UNIX Spec and I prefer to follow standards unless you have a radically better idea (similar to the use of Ada).

Previous recommendations, including whining that ncursesada wouldn't work for me

Home of the Single UNIX Spec, see the "Publications Library" link

However, something has bothered me for some time, and I've seen a few others report the same problem. The maintained Ada bindings to ncurses are only for "narrow" (i.e. 8-bit) locales. I'm a bit of a Japanophile, but a different project that exposes the "wide" API to support locales like CJK won't compile and from the defect database seems to be unmaintained. I have no intention of forking/starting a whole project, so was happy to find a lazy way to fix the problem.

Official bindings. Note the last point in "General Remarks".

Someone who dropped back to C for the UI layer

Moribund project that might have done the job, but didn't

It's possible to just add a few new bindings to the existing ncursesada library, from your own code. Specifically, for Ubuntu 26 (and similar):

FFI Bindings

This was an opportunity for me to learn how to use the Interfaces.C package from the standard library. As expected, it's complete but note that it works at the linker level so preprocessor symbols aren't available. This is only a minor limitation. For an experiment, I exposed one new curses function, `waddnwstr`, to display a wide string. There are probably only a few more required for a complete interface, e.g. display character, input string & character, wide version of the line-drawing support.

The standard Interfaces.C package

These are the packages we use:

This is the new public interface we're implementing. Terminal_Interface.Curses is the official binding package.

This is the private implementation, including an instance of what seems to be a common pattern where there is a thin wrapper around the C interface ("Waddnwstr" below) and a slightly nicer one using Ada types ("Add"). It was adapted from the narrow implementation in the official bindings and only required minor changes.

You just need to put this into a file terminal_interface-curses-ext.adb in your project's source directory.

The required .ads file is trivially derivable from the .adb file and left as an exercise for the reader ;-).

Gprbuild Support

This was even easier. I just copied /usr/share/gpr/ncursesada.gpr to the current dir and modified all strings like "-lncurses" to "-lncursesw" (and although I don't use them, similar for form, menu & panel).

Then you can "use" this new gpr file from your project's gpr file and everything *seems to* link correctly. At least, my trivial test worked.

Conclusion

After trying a few different ways, I think I may have found the laziest way to write a Japanese TUI in Ada. Maybe not many other people will want to scratch that itch, but it's out there for anyone who does.

Postscript

Looking back at some of the Ada libraries I recommended in the previous post mentioned at the top of this one, I think I'd change a few other things.

Simple Components, a library I'm currently studying

Alog library

Back to my gemlog

Proxied content from gemini://republic.circumlunar.space/users/dbane/gemlog/2026-05-12.gmi (external content)

Gemini request details:

Original URL
gemini://republic.circumlunar.space/users/dbane/gemlog/2026-05-12.gmi
Status code
Success
Meta
text/gemini
Proxied by
kineto

Be advised that no attempt was made to verify the remote SSL certificate.