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.
Related
Im a newbie and want to know if this is possible so that it may help in my project which is only in c++. This is something similar to "uigetfile" in matlab.I use Ubuntu.
Thanks in advance.
You will need to add windowing capability to your program. The standard C++ language has no facilities for dialog boxes.
Windowing is platform specific. You may find windowing frameworks that are cross-platform.
Dialog box creation is either OS dependent or windowing framework dependent.
You didn't specify in your post the OS you are using.
Graphical User Interfaces (GUI or UI) are very complex systems that depends on many layers of hardware and software:
The hardware, especially the graphic card help for drawing and showing the result on screen.
Driver: To access the Graphic card. This is already platform-dependent.
Operating system: Give you facilities to user the graphic card and usually a library for drawing your GUI.
This mean, there is not a standard way to make a GUI, and that C++ stay outside of the mess.
However, some libraries abstract the different systems and provide single API for creating GUI, this obviously relay on the library having implemented the specific platform details, so it will never be 100% cross-platform.
Examples of GUI libraries are:
QT (e.g. used for KDE)
GDK (e.g. used for GNOME / UNITY)
wxWidgets
...
I need the Linux equivalent for the following Windows code:
auto touchCap(GetSystemMetrics(SM_DIGITIZER));
if (!(touchCap & NID_READY)) LOG("WARNING: No active digitizer detected")
if (!(touchCap & NID_MULTI_INPUT)) LOG("WARNING: No multi-touch digitizer detected")
Note that it's not checking if a touchscreen driver is simply present, but if there is a currently active touch device. I also need to know if it's multitouch or not.
There might not be an exact equivalent, as I have seen differences in the way Windows and Linux event libraries are designed, but have you taken a look at the SDL Library? This is the event library that I have seen used for some recent Linux projects.
https://wiki.libsdl.org/
I've also heard that SFML is pretty nice.
http://www.sfml-dev.org/
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..
Both Windows (Win32 API) and OS X (Cocoa) have their own APIs to handle windows, events and other OS stuff. I have never really got a clear answer as to what Linux’s equivalent is?
I have heard some people say GTK+, but GTK+ being cross platform. How can it be native?
In Linux the graphical user interface is not a part of the operating system. The graphical user interface found on most Linux desktops is provided by software called the X Window System, which defines a device independent way of dealing with screens, keyboards and pointer devices.
X Window defines a network protocol for communication, and any program that knows how to "speak" this protocol can use it. There is a C library called Xlib that makes it easier to use this protocol, so Xlib is kind of the native GUI API. Xlib is not the only way to access an X Window server; there is also XCB.
Toolkit libraries such as GTK+ (used by GNOME) and Qt (used by KDE), built on top of Xlib, are used because they are easier to program with. For example they give you a consistent look and feel across applications, make it easier to use drag-and-drop, provide components standard to a modern desktop environment, and so on.
How X draws on the screen internally depends on the implementation. X.org has a device independent part and a device dependent part. The former manages screen resources such as windows, while the latter communicates with the graphics card driver, usually a kernel module. The communication may happen over direct memory access or through system calls to the kernel. The driver translates the commands into a form that the hardware on the card understands.
As of 2013, a new window system called Wayland is starting to become usable, and many distributions have said they will at some point migrate to it, though there is still no clear schedule. This system is based on OpenGL/ES API, which means that in the future OpenGL will be the "native GUI API" in Linux. Work is being done to port GTK+ and QT to Wayland, so that current popular applications and desktop systems would need minimal changes. The applications that cannot be ported will be supported through an X11 server, much like OS X supports X11 apps through Xquartz. The GTK+ port is expected to be finished within a year, while Qt 5 already has complete Wayland support.
To further complicate matters, Ubuntu has announced they are developing a new system called Mir because of problems they perceive with Wayland. This window system is also based on the OpenGL/ES API.
Linux is a kernel, not a full operating system. There are different windowing systems and gui's that run on top of Linux to provide windowing. Typically X11 is the windowing system used by Linux distros.
Wayland is also worth mentioning as it is mostly referred as a "future X11 killer".
Also note that Android and some other mobile operating systems don't include X11 although they have a Linux kernel, so in that sense X11 is not native to all Linux systems.
Being cross-platform has nothing to do with being native. Cocoa has also been ported to other platforms via GNUStep but it is still native to OS X / macOS.
Strictly speaking, the API of Linux consists of its system calls. These are all of the kernel functions that can be called by a user-mode (non-kernel) program. This is a very low-level interface that allows programs to do things like open and read files. See http://en.wikipedia.org/wiki/System_call for a general introduction.
A real Linux system will also have an entire "stack" of other software running on it, in order to provide a graphical user interface and other features. Each element of this stack will offer its own API.
To aid in what has already been mentioned there is a very good overview of the Linux graphics stack at this blog: http://blog.mecheye.net/2012/06/the-linux-graphics-stack/
This explains X11/Wayland etc and how it all fits together. In addition to what has already been mentioned I think it's worth adding a bit about the following API's you can use for graphics in Linux:
Mesa - "Mesa is many things, but one of the major things it provides that it is most famous for is its OpenGL implementation. It is an open-source implementation of the OpenGL API."
Cairo - "cairo is a drawing library used either by applications like Firefox directly, or through libraries like GTK+, to draw vector shapes."
DRM (Direct Rendering Manager) - I understand this the least but its basically the kernel drivers that let you write graphics directly to framebuffer without going through X
I suppose the question is more like "What is linux's native GUI API".
In most cases X (aka X11) will be used for that: http://en.wikipedia.org/wiki/X_Window_System.
You can find the API documentation here
XWindows is probably the closest to what could be called 'native' :)
The linux kernel graphical operations are in /include/linux/fb.h as struct fb_ops. Eventually this is what add-ons like X11, Wayland, or DRM appear to reference. As these operations are only for video cards, not vector or raster hardcopy or tty oriented terminal devices, their usefulness as a GUI is limited; it's just not entirely true you need those add-ons to get graphical output if you don't mind using some assembler to bypass syscall as necessary.
Wayland
As you might hear, wayland is the featured choice of many distros these days, because of its protocol is simpler than the X.
Toolkits of wayland
Toolkits or gui libraries that wayland suggests are:
QT 5
GTK+
LSD
Clutter
EFL
The closest thing to Win32 in linux would be the libc, as you mention not only the UI but events and "other os stuff"
GUI is a high level abstraction of capability, so almost everything from XOrg server to OpenGL is ported cross-platform, including for Windows platform. But if by GUI API you mean *nix graphics API then you might be wandering around "Direct Rendering Infrastructure".
The subject says it all - normally easy and cross platform way is to poll, intelligently. But every OS has some means to notify without polling. Is it possible in a reasonably cross platform way? (I only really care about Windows and Linux, but I use mac, so I thought posix may help?)
Linux users can use inotify
inotify is a Linux kernel subsystem
that provides file system event
notification.
Some goodies for Windows fellows:
File Change Notification on MSDN
"When Folders Change" article
File System Notification on Change
The Qt library has a QFileSystemWatcher class which provides cross platform notifications when a file changes. Even if you are not using Qt, because the source is available you could have a look at it as a sample for your own implementation. Qt has separate implementations for Windows, Linux and Mac.
There's File System Events API as of Leopard.
I don't think POSIX itself has facilities for that. The closest to cross-platform I've seen is FAM, which seems to work for Linux, BSD, and Irix, but I'm not how easy it would be to port it to Windows and MacOS.
I've actually built this system before for use in a commercial C++ code base- as long as you don't need every weird thing under the sun, the Windows and POSIX systems have a lot of overlap you can abstract.
POSIX: Use inotify- it is a whole system literally built for this job
Windows: Use "change events". You have to build more of the glue and reporting yourself (all the APIs you need are available, there's just not the 1-stop-shopping inotify gives you).
The common things you can detect in your "notification thread" for forwarding events are:
1) Basically any invasive operation boost::filesystem supports, with the (possible) exception of modifying permissions. This is things like moving, creating, deleting, copying folders and files.
2) Reads and writes to files (esp. writes). Be aware that if you're using async I/O the notifications can show up out-of-order.
3) When a new volume comes in, such as somebody connecting a flash drive.
inotify especially gives you an insane level of fine-grained control, Windows less so. With inotify you can literally monitor everything the filesystem is doing in near-real time if you really want to. I know #3 is possible with both without polling, but be aware that it can be really tricky to get it working correctly- on either system.
I believe OS X now has appropriate hooks/callbacks because they were needed for Spotlight indexing.
On linux you'll have the additional trouble that there are multiple file systems commonly used. If you need the functionality for only a limited amount of files/directories, I'd try about actively looking for modifications at regular intervals.
libevent or libev seem to be what you want, though I haven't used them.