Edit on 2022/12/23: check this article for another approach: X11 and multithreading.
In this article I'll show how to implement a simple interactive graphical display in C using GTK. GTK is a free and open-source cross-platform widget toolkit for creating graphical user interface. It's easy to use and extremely powerful, but has so many features a beginner may feel intimidated with it, and even a more advanced user may think there is too much work to do to only display some simple graphics. The goal of this article is to provide a structure hiding all the GTK mechanics and allowing the user to display and interact with a RGB image, in less than 10 lines of code.
From the user's point of view, displaying RGB images on the screen should really not look more than something like this:
The display should run in parallel, not blocking the user code, and the user should not have to bother about its internal mechanism. It should also be dynamic, if the user updates the graphic with DisplaySetPixel() after showing the display, it should reflect the change. Several displays in parallel should be possible (with no assumption of their order of creation, update and destruction). And finally to make it interactive, there should be a DisplayGetKeyPressed() function to detect and react to key press events on the display. I'll restrain here the functionality to key press but it's straightforward to extend it to mouse events. I'll also impose the display to be non resizable, and don't worry about double buffering during display, as it makes things much more simple and should be already enough to cover many cases. Of course, feel free to extend the code below to fit your need.
Rhe display will run in its own process, spawned when it is shown. A shared segment of memory will be used for interaction between the user code and the process managing the display. And as I said, all the GTK stuff to actually display the window and manage it will be done in the display process. If you really only care of using it, the code of display.h and display.c is available at the end of this article. Copy it and start using it as in the example above. This structure is also available in my LibCapy library as the CapyDisplay class (also providing more functionalities). Instead, if you're interested into how it's implemented, here comes the explanation.
Include the needed headers for GTK and shared memory segments:
The Display structure definition:
Definition of the DisplayCom structure (shared data between the user process and the Display process for interaction):
Declaration of the interface of the Display structure:
Definition of each function of the interface:
Private functions of display.c:
Finally, the whole code for the Display structure. display.h:
display.c:
Compile with gcc -std=c18 -Wall -Wextra `pkg-config --cflags gtk+-3.0` -o main main.c display.c `pkg-config --libs gtk+-3.0`.