How to create a console terminal? - c++

From where I can start creating a console for my C++ programs ?
I need a bare minimum console to launch and manage console applications, the reason why I need this it's because I need to pack everything into 1 executable and create and control my little environment.
With the term "console" I only mean a terminal to run my program, nothing more, nothing less, I don't want my console to be interfaced with the underlaying system, only care about my console applications.
So my question is: given a C++ applications or a command line interpreter, what is the know-how required to create a terminal that is able to interface itself to this application and report and manage the usual input ( std::cout, special characters like bells, text input from the user, and so on ) ?

I think this is a WAY too large question for "one answer".
There are three components to the problem:
Running another application from your code.
Capturing the output of said application.
Displaying the output in a console type window.
I believe at least 1 & 2 are decidedly different for each major type of platform, at the very least it is different on Windows vs. Symbian vs. Linux/Unix type platforms. I believe, largely, an Android platform can achieve this by the same method as Linux.
The third part, aside from all the complexities of emulating a VT100 or ANSI terminal (which is non-trivial because there is a large number of different escape-codes to parse and interpret, but you can probably get away with just implementing half a dozen or so to begin with).
I'd expect, aside from "platform specific code", this is a project that requires a few thousand lines of code, and if you know where to start (that is, you are familiar with fork(), execl() etc in Linux or their equivalents in another OS, and familiar with redirection if stdin, stderr and stdout using dup2() and similar functions, again with reservation for OS specific names, you could have something that roughly works in a few weeks. If you have no idea about these things, you will have to learn how to use these features first.
Of course, doing terminal emulation, such as "draw a line of text here", "insert an empty line at line X", "clear screen from this position" or "clear remaining line", etc, etc will require a fair amount of work to cover ALL the different variants and options. Especially if you wish to do this on a variable size display, rather than a "fixed 80 columns and 25 rows" as the original VT100 terminals supported. And I'm assuming you have already written code to draw basic text in OpenGL or OpenVG (does OpenVG support text natively, or do you have to do that as "draw bitmap" - I can't remember exactly how it works - I wasn't one of the people working on text in Symbian Graphics, so I was never really concerned with how it worked).

Related

How to override/disable ncurses input?

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.

linux application to control optical media

I want a graphical application for Linux that displays the contents of CD/DVD/blu-ray drives and allows play or eject, and I'd like the solution to be general, so that I can donate it to Linux Mint, that is any drive type and any number of drives. In my system I have three dvd drives and a blu-ray drive.
I'd like to write it in bash using the dialog functions inside a terminal window but I need to have the dialog displayed in perpitude therefore, I need an interrupt to signal when the drive is opened or closed - what signal could I trap? Also, how can I include logic to select a program to play the media depending on the media type.
Also, should I consider writing it in java, python, C++, or other language and if so how to get hardware information (such as the number and capability of drives, and the type and title of optical media in drive)?
Ignoring the side of "I want to donate this to Linux Mint", which I believe is a bit pretentious, there is a eject utility in Linux.
The source code of that can be found here:
https://git.kernel.org/cgit/utils/util-linux/util-linux.git/tree/sys-utils/eject.c
In that code, there is also code to sense if the drive is open, closed, has no disk, etc.
To do CD or DVD playback is a whole other kettle of fish. To write a audio-player is not entirely trivial (even in the simple case of a straightforward PCM encoding, obviously MP3 is a fair bit more complex again), and a video-player is a lot more than that.
To "select a program", you'd have to know what the available players may be called, and, if you want to be fancy, check which ones are actually installed. I'm not aware of any really clever way of achieving that, beyond having a list of players in your code (which needs to be updated). In fact, I know that is how the photo viewer geeqie works when you want to edit a shot: it has a list of "known editors", and it scans the PATH to find which ones are available.

Reading arrow keys with C++

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.

How is the UI of terminal texteditors implemented?

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

Move Window Linux C

i'd like to make a function that can move a window in Linux in C++ by its PID. So I've tryed in under Windows. But I have trouble to compile it for Linux.
Is there any mean to do it with Qt ? Since I haven't found one, I've tryed to compile for Linux.
I'm using the MoveWindow function, which is part of the Windows API. Is there any Linux equivalent ?
You don't have to do that by hand if you don't really want to as there already are lots of tools out there, that can perform such tasks as moving, resizing, maximizing and whatever windows.
One tool you might want to take a closer look upon goes by the name of wmctrl even if you don't intend to use maybe you'll find some interesting tricks by taking a look into the sources.
The task of moving a window only known by the pid of the client that created the window might not be the easiest tasks of all for a couple of reasons.
First of all you really shouldn't try to do this as in the X Windows philosophy it is the job of the window manager to arrange the windows on the screen.
As well ICCCM (see: http://de.wikipedia.org/wiki/Inter-Client_Communication_Conventions_Manual) as the EWM spec (see: http://standards.freedesktop.org/wm-spec/wm-spec-latest.html) strongly discourage any client from trying to move resize or whatever on its own. Most probably moving windows "owned" by another client might be considered even bigger evil.
The second problem you might face is, that the X 11 protocol doesn't have any notion of pid.
As it was designed to be used over a network you never can't be really sure the program runs on the same machine as the one you are currently sitting in front of. As such there isn't much sense in something like a pid as by chance there might be any number of clients with identical pids displaying windows on the same X Server if they ran on different machines.
Fortunately enough it is not all that bad, as the EWMH spec encourages any client to set the _NET_WM_PID property on its top level window the the pid of the client that created the window.
Again adhering to the EWMH spec isn't enforced by the X Server in any way so that while practically propably almost all clients will set it there's still no guarantee you'll find the window belonging to a specific pid.
Possibilities
While the whole points mentioned until here might seem rather limiting in fact most probably rather the opposite is true. Even because practically it is relatively easy to totally mess up any other client running in an X session the whole set of rules about how to be a good citizen in the X word were introduced.
As the X11 protocol itself is a network protocol (well not 100% true as locally running clients most probably will be communicating with the X Server via a UNIX domain socket) there isn't any specific library required to talk to the X Server.
Talking about C as mentioned in your question the Xlib has long been the one and only one implementation in wide use but there's also another binding called xcb. With a slightly changed API in comparison to the Xlib.
Xlib
Speaking Xlib I've never ever used any xcb until now, so I can't tell you too much about it might be the following methods that might be of use.
XOpenDisplay - open connection to the X server
XQueryTree - aquire the tree of windows currently alive on the server
XInternAtom - no fear it isn't dangerous. Just read about it in the manuals as you'll need it the get the "atom" mapping to _NET_WM_PID mentioned above
XListProperties - search for the _NET_WM_PID property with the value you are looking for
XConfigureWindow, XMoveWindow, XResizeWindow, ... - to finally perform whatever you wish to do.
All functions mentioned above should be documented in the manual pages. Just use man XOpenDisplay for example.
Oh, and be sure to learn about all the other tools at your disposal to further investigate about the X Window world. Run xlsatoms, check what xwininfo reports an take a list at the output of xprop for one single (!) window alone. Try to set some yourself to see what happens xprop will even do that for you if you ask politely.