Terminal texteditors like emacs,vim,joe or even nano have the ability to display arbitrary UI elements inside a command line without completely rewriting the whole UI every single time, but overwriting what currently is their UI.
With regular output streams, you can only use the return character '\r' to jump to the beginning of the current line of output and write over it, but from what I found you can not jump up multiple lines, cout << "\r\r\r\r\r\r"; has the same effect as cout << '\r', so everything followed by a newline is apparently cast in stone.
Other applications do something similar, for example $dpkg-reconfigure ca-certificates on Ubuntu or the aptitude graphical package manager. They also draw outlines for UI elements, which are probably just special characters. But still, they'd have to overwrite multiple lines of console output.
How do they do that? Is the behaviour portable to Windows platforms?
You'll find that these programs depend on a library called ncurses:
http://en.wikipedia.org/wiki/Ncurses
There are builds available for almost all operating systems.
curses is a unix library that lets you manipulate the contents of a terminal at arbitrary positions. ncurses is a free, vendor-independent version of curses, and the curses library used on linux.
dpkg-reconfigure uses dialog that builds on top of curses and provides user interface widgets instead of raw terminal access.
ncurses includes the extensions "menu", "forms", "panel" that you could use to implement user interface widgets yourself, though it gets very complex very quickly if you go that route.
Regarding windows, there is pdcurses that runs natively in the "dos box" terminal. You can write portable programs that use pdcurses on windows and ncurses on linux if you restrict yourself to the common subset. Alternatively, you can use ncurses on windows using cygwin.
Another alternative for windows might be Borlands TVision - if you can find an old version of Borland's turbo pascal or c++ compiler, they included a complete application framework for text user interfaces called TVision. Not sure if the code generated by these would still run on modern windows versions, though.
The console follows a specification:
https://www.xfree86.org/current/ctlseqs.html
This is similar to a client/server. If you application (the client) follows the same specification, it can communicate with the console via the standard input/output to draw anything its wants.
There are many things in the specification:
Clear a specific line.
Move the cursor
Set background/foreground color.
Set style: bold, dim, underlined, blink, ...
Request sending mouse events, receive mouse events.
Configure the console to nowrap/wrap lines.
Configure the console to use the "alternate" screen.
etc..
Related
I'm writing a code, and I'd like to make it in two variants - with text-based interface (TUI) implemented with ncurses, and with GUI implemented with Qt5. So, passing an argument in the command-line, I can choose which version to run - with GUI or TUI (e.g., just like with YaST in openSUSE). The rest of the code, including inputs from the keyboard, should be independent of which interface (TUI or GUI) is chosen. As I see it, the optimal way to implement such a program is to use distinct classes for input, for user interface, etc. So, in whatever version I run the code, the class handling the input should be the same, and it passes the data to the interface class, which might be TUI or GUI, depending on how the application was launched. The problem is that for ncurses it seems impossible to detach input from the output. Basically, what I want is to still be able to use ncurses output (windows, panels, etc.), but to perform input with some other library. Anyone knows how to solve that? Also, what input C/C++ libraries can I use for reading keyboard event in whatever mode (terminal or GUI)?
You do not have to use ncurses' input-functions (such as wgetch) when using ncurses for output.
A few programs do this (Midnight Commander, vi-like-Emacs) because they use inputs that largely are not resolved to special keys using ncurses, such as
the escape character by itself (vi-like-Emacs), or
the mouse-code in Midnight Commmander (which uses select for monitoring multiple inputs).
Managing different output streams actually can be more difficult, since those use information about the appearance of your program on the computer screen. Inputs usually do not occupy more than a line or so of the screen.
In vi-like-Emacs, the program uses a terminal-driver which knows how to work with a specific type of device (terminal emulator, X windows, Win32 GUI), and the program is compiled and linked with that driver. It would be nice to be able to switch between drivers at runtime, but nuances of mouse-handling are harder to factor out than keyboard input and screen updates.
I would like to write a console app with text UI in D. I looked at curses, but it seems that it works only on unix. Are there any cross-patform alternatives?
My terminal.d could be used as a foundation for a TUI library.
https://github.com/adamdruppe/arsd/blob/master/terminal.d
It has no required dependencies, so you can simply download that one file and start building with dmd yourfile.d terminal.d. Here's an example program getting input: http://arsdnet.net/dcode/book/chapter_12/07/input.d
You can also use terminal.moveTo(x, y); terminal.color(Color.green, Color.black); terminal.writef("something"); terminal.flush(); and such to move and draw.
Look for version(Demo) in terminal.d itself for a main which handles all kinds of input events, including mouse events.
While terminal.d mostly offers lower-level functions (its main high level function is terminal.getline, great for line based apps but not TUIs), it should give all the foundation needed to write a little text widget library.
and I think someone might have done that once but I don't recall where.
terminal.d works on Windows and Posix systems, for the most common terminals like xterm. ncurses is more comprehensive and probably has fewer bugs on more obscure targets but terminal.d, being a single file, is easier to build.
That was true long ago. However, ncurses is known to work nicely on Windows as well. The easiest way to build it on Windows is inside the MSYS2 shell. There is really no other cross-platform alternative to Curses (find out why they named the project "curses" and you will find why there is no good alternative).
I am writing an C++ Application and have to read if an arrow key is pressed or not.
I only found some function that are only working on Windows.
You have such problem because you just ask the wrong question. If you application is a command line tool and is accessible from a terminal, than it's just impossible to know which keys are pressed at the moment because the terminal can be far away from the machine where your application runs and which is more important, there is no reason for terminal to send you the arrow key presses because terminal can use them for text navigation.
So you may search how to make the terminal to send you key presses. Not every terminal will support it, but, I think, most of modern terminals in modern OS do.
If you has a gui application that is for running locally and assuming that you control it from the keyboard that is plugged in. Than you should search for the documentation for your gui toolkit. (Qt, wxWidgets, raw xorg, windows API, etc.)
So there are just no native C++ solution for this problem because you question just has no sense in many situations.
So you can use some console library like ncurses or gui toolkit like Qt or search for a native solution in your particular situation, but don't expect this last way will work without any additional code on other machines.
Or just search for other libraries that can allow you to do it.
As you say you only found material for Windows, I assume you are looking for a Linux-Unix way. Old dinosaurs like me remember the time when we only had true consoles (only a keyboard and a 80x25 display). And in these early times existed low-level libraries to interpret keypad transmitted keys and position cursor on screen on almost any terminal, and higher level ones to use the screen as a (text only) GUI.
You should look for curses or ncurses for high level libraries, and terminfo for the low-level capabilities.
I have a lot of simple C++ programs that I've written in XCode, using OpenGL and Glut to visualise scientific data. It works very well, but there is one minor annoyance: every time I run one of the binaries from outside of XCode, it opens a Terminal window. This means I get a crusty build-up of Terminal windows that has to be cleaned up after use.
Is there a way to prevent this from happening? I'm hoping for a quick solution to a very minor problem, so anything that requires me to learn Objective C or some fancy GUI creation tool isn't what I want. I just want to know if there's a way to compile my existing C++ Glut apps in such a way that the terminal window won't appear when you click on the icon.
Sort of... Basically, you need some kind of OS X wrapper to contain the binary. You can do this with Automator or AppleScript or with a tool like DropScript, which is designed to encapsulate unix binaries.
Otherwise, the solution for this would be to create a minimal Objective-C program and then she'll out the unix binary from within it, so that when it terminates it doesn't leave any residue.
I am building cross-platform game engine and now I am focused on Input system.
I have written an abstract Input system which passes the messages up
and is beeing fed by platform dependent modules, running in separate thread.
In windows I have created "Message-only" window, which feed Input
system with messages (translated to platform independent) from RAWINPUT.
Now I am having troubles to figure out how to do similar thing on unix based system.
Is there any convenient way to get input (keyup, keydown, mousemove...) from kernel?
Or any other way without need showing any window?
EDIT
I do not want to my Input System be dependent on my Renderer. Renderer should just notify
input when app focus changed... So I want Input system to run on different thread than renderer.
Usually cross-platform input is achieved by using a wrapper library -- SDL is one that is pretty good at that, and the current version is even BSD licenced.
The advantages of using a wrapper are so big, that even Windows games that use their own solution on Windows tend to use SDL as a wrapper when running on Linux (that was the original reason SDL was created).
So in the worst case, you may keep your libraries on Windows, and use SDL for implementation specifically on *nix systems.
Assuming you're using X11:
Peter Hutterer has a series of XInput2 articles. Supports raw events apparently.
ManyMouse claims to use XInput2 without a window:
On Unix systems, we try to use the XInput2 extension if possible.
ManyMouse will try to fallback to other approaches if there is no X server
available or the X server doesn't support XInput2. If you want to use the
XInput2 target, make sure you link with "-ldl", since we use dlopen() to
find the X11/XInput2 libraries. You do not have to link against Xlib
directly, and ManyMouse will fail gracefully (reporting no mice in the
ManyMouse XInput2 driver) if the libraries don't exist on the end user's
system. Naturally, you'll need the X11 headers on your system (on Ubuntu,
you would want to apt-get install libxi-dev). You can build with
SUPPORT_XINPUT2 defined to zero to disable XInput2 support completely.
Please note that the XInput2 target does not need your app to supply an X11
window. The test_manymouse_stdio app works with this target, so long as the
X server is running. Please note that the X11 DGA extension conflicts with
XInput2 (specifically: SDL might use it). This is a good way to deal with
this in SDL 1.2:
Might be worth looking through the source.
Under X Window system there is a concept of input-only windows, which is more or less parallel to that of message-only window under Windows.