site  contact  subhomenews

Statically-linked gui_engine example with TTF support is 560KB

January 18, 2023 — BarryK

I originally posted about gui_engine here, it runs as a statically-linked binary in the initrd:

Then posted about success with SDL_ttf:

So, compiled SDL-ttf and dependencies freetype and libpng, as static libraries, in OE, then added some SDL_ttf functions into 'example.c' in gui_engine. The compiled example.c, linking in those extra libraries. The statically-linked binary was 304KB, it is now 560KB.

I reckon that is very good. A completely standalone application, with SDL, SDL_gfx, SDL_ttf, freetype, libz and libpng all linked-in, very reasonable size.

The 'example.c' is now ready to be expanded, render TrueType fonts instead of console fonts, add one or two extra widgets -- I would like a list widget, to show the list of languages, as did earlier using 'dialog' in the initrd.

It is all very well wanting to do the above, but first have to study the code of gui_engine, figure how it all hangs together.  

Tags: easy

Learning SDL v1.2 Lesson 08

January 17, 2023 — BarryK

I posted that came to a stop at Lesson 07:

And jumped that hurdle:

Lesson 08 is here, introducing key presses:

Compiled and tested:

# g++ -o lesson08 lesson08.cpp -lSDL -lSDL_image -lSDL_ttf -lfreetype
# ./lesson08

Very good. Now back on gui_engine, the simple widget toolkit. I mentioned that there is no way to exit:

If compiled for the desktop, with SDL using X11, then the example app runs in a window, and can be closed via the window close-box. On the framebuffer though, there is no close-box.

So, I was keen to learn how to handle key presses. Easy peasy to add detection of pressing the ESC key and exit the program. You would have to download gui_engine to see the entire 'example.c', just showing what I inserted, shown in bold text:

  /* Main loop. */
bool running = true;
SDL_Event event;
if(event.type == SDL_QUIT)
running = false;
if(event.type == SDL_KEYDOWN)
if(event.key.keysym.sym == SDLK_ESCAPE) running = false;

The key symbols are tabulated here:

Very good. Next up, want to investigate incorporating a TTF font.  

Tags: easy

Back in business with SDL_ttf

January 17, 2023 — BarryK

I posted about starting to learn SDL v1.2 coding, then came to a halt at Lesson 07, when a SDL_ttf function failed:

I suppose that I could trace the code, find where the function is failing; however, I took a punt. Sometimes, older versions of a package are better. Developers may start off with something that works, then they add more features and clever things.

My punt is, went to the SDL source releases site, and downloaded one of the first SDL_ttf packages that supports freetype2; package 'SDL_ttf-2.0.3.tar.gz':

Compiled it:

# ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --build=x86_64-pc-linux-gnu
# make
# make install

And it works! So ancient, 2.0.3 was released in 2001. That's one of the great things about C code, ancient code still compiles.

I got a test program from Matt Wilson:

...used 'lazy.ttf' from Lesson 07, and it worked. So then tried Lesson 07 again:


Good, on to Lesson 08!    

Tags: easy

More old widget libraries for SDL 1.2

January 17, 2023 — BarryK

There are so many old projects. If you keep looking and looking, using different search keywords, more old treasures are discovered. And links to no-longer-existing projects.

I have been posting about GUI toolkits that run on SDL 1.2, such as gui_engine:

Was googling a bit more yesterday, and came across three more old toolkits that use SDL 1.2:

I only compiled RetroGui, and yes it works. It requires "-fcommon" appended to CFLAGS in the Makefile. It has more widgets than gui_engine, so could be a source of ideas if want to add to gui_engine.  

Tags: easy

Started learning SDL v1.2 came to a stop

January 16, 2023 — BarryK

As posted yesterday, I'm a glutton for punishment sometimes. gui_engine looks good: is just using a console font, but to make it really useful, want a font with full UTF-8 support. So, would be good to bring in the 'libsdl-ttf' package. So, with this in mind, started going through some SDL v1.2 tutorials. Here are my notes:

creates a window with a bmp image filling it, waits 2 secs then quits.
# gcc -o lesson01 lesson01.cpp -lSDL

multiple images in window.
# g++ -o lesson02 lesson02.cpp -lSDL
# ./lesson02

# g++ -o lesson03 lesson03.cpp -lSDL -lSDL_image
# ./lesson03

event loop: click close-box top-right of window, correctly exits.
# g++ -o lesson04 lesson04.cpp -lSDL -lSDL_image
# ./lesson04

overlay two images, with a transparent colour in top image.
# g++ -o lesson05 lesson05.cpp -lSDL -lSDL_image

sprite sheets
# g++ -o lesson06 lesson06.cpp -lSDL -lSDL_image
# ./lesson06

truetype fonts
link to official SDL_ttf documentation tarball:
# g++ -o lesson07 lesson07.cpp -lSDL -lSDL_image -lSDL_ttf -lfreetype
# ./lesson07
ERROR loading font
modified the code:

//Open the font
//font = TTF_OpenFont( "lazy.ttf", 28 );
font = TTF_OpenFont( "/usr/share/fonts/TTF/DejaVuSans.ttf", 28 );

//If there was an error in loading the font
if( font == NULL )
printf("ERROR loading font\n");
return false;

downloaded SDL_ttf-2.0.11, applied some patches from debian, compiled:
# ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --build=x86_64-pc-linux-gnu
# make
# new2dir make install
...nup, same error

...I put that "printf()" to confirm the "TTF_OpenFont()" is failing. Tried a different font, with full path, no go. Recompiled SDL_ff-2.0.11 package, with latest patches from Debian, still no go. Huh, what to do next?

Very frustrating. In the last couple of days, I mentioned checking out other GUI toolkits that will work with the Linux framebuffer, either directly of via SDL v1.2. Recollecting, I think there was only one that could talk directly to the framebuffer; LVGL.

I like LVGL, and have looked at it in 2018:

Yes, the mouse works, unfortunately not the keyboard. Like many of these GUI toolkits targeting embedded systems, they are touch-oriented, or for keypads on specific devices. I raised the issue of the keyboard in a PC:

...tentatively posted some code showing how the keyboard and mice can be detected. But I lacked the knowledge how to integrate this into LVGL, so hoped someone would pick it up. But here we are in 2023 and no one has.

Yesterday I looked around the LVGL source code, no, it is very obscure, cannot see how to bring in PC keyboard support. It would take considerable time, to study how it all hangs together. So, unfortunately, that's another GUI toolkit that has to be abandoned.

Back on the subject of SDL, early versions of LVGL have a method of using fonts, such as DejaVuSans, converted to bitmaps. That code could be ported to gui_engine, to avoid SDL_ttf.

SDL_ttf fixed!!! See later blog post:

Next stop, Lesson 08!    

Tags: easy

gui_engine runs in initrd

January 15, 2023 — BarryK

I posted yesterday about compiling 'dialog' statically, enabling text-mode GUIs in the initrd:

'dialog' is completely stand-alone, doesn't require any shared libraries, and is 508KB. It supports unicode characters.

All of the utilities in the initrd are statically-linked; 'busybox' is another example.

Over the years I have looked at various ways to run a GUI app in the initrd. For example, these blog posts:

Being a glutton for punishment, decided to give it another go. Started early yesterday, it has been a marathon session, now 3.30am -- have to be up by 8am, going to a family gathering -- will post this report then sleep.

Here are some of the GUI toolkits that I looked at:

fbwhiptail, guilib, guilite, lcui, libagar, minigui, picogui, tekui, ugfx, lvgl, microwindows, nuklear

...they all have some problem, such as too complicated, too bloated, don't work properly, or even don't work at all. etc.

I need a toolkit that will work with the Linux framebuffer, either directly or via an intermediary library such as sdl 1.2. I found sdl 1.2 to be best for getting keyboard and mouse to work.

For sdl 1.2 to be used, it has to be a .a static library file, without any dependencies, so can be linked to build a statically-linked application. I configured sdl and sdl-gfx as small as possible, for the framebuffer only, see OE project commit:

I found a fascination project, 'GUIslice', that will use sdl 1.2 backend. The docs even claim can use the framebuffer directly; however, I discovered in practice was unable to do certain things claimed in the documentation. For example, it is supposed to be able to disable touch screen requirement, but was unable to do that -- it insisted on needing 'tslib'. Anyway, the project page:

Also, only one of the examples worked, the rest aborted at startup. It has a fantastic GUI-builder, that does work:

I would like to study GUIslice some more, see if can get it to work. However, right now have another GUI toolkit, 'gui_engine', that works great. Project page:

The link has a nice GIF animation, but here is my snapshot, running in the initrd:


The example is named 'example' and is 304KB. That is a statically-link standalone application. Most of the size is the linked-in libsdl, so adding more features to the app won't increase the size much.

Very limited widgets, no documentation, but very simple and small C code. So definitely interested in taking it on as a project. Might be of interest to someone else also. First task -- there is no way to exit from the example, had to do a hard power-off.

Anyway, this evening intend to have another look at GUIslice.    

Tags: easy

First bootup 2-letter language asked in initrd

January 13, 2023 — BarryK

The method used to translate the scripts in the initrd has varied over the years. At one stage, I tried the gettext method. Prior to now, it has been the "sss" method; "simple string substitution", in which the strings in a script are completely replaced, resulting in a non-English script.

The latter method is clumsy, for various reasons. For example, if you want to change the scripts to a different language, copies of the original scripts in English have to be kept -- though, I have implemented a devious method of translating the non-English script back to English, then to another language. There are other problems also.

After some indecision, I have implemented a fairly simple and flexible system. All of the strings that a script will echo to the screen have been taken out to a separate file. This file is simply a list of variables, like this example, part of '/nls/':

S010='ERREUR :'
S011='Sont maintenant tombés dans un shell dans initramfs.'
S012='Veuillez appuyer sur la combinaison de touches CTRL-ALT-DEL pour redémarrer,'
S014='Les instructions suivantes sont réservées aux développeurs :'

The '' file is just included into the script by the "source" or "." command. This allows very easy flipping a language within the script.

So far I have created .fr, .de and .it translation files, but it is very easy to create them. I just go to and paste the content of the .en file and select target language and in a minute have a translation. These translations will all be in the initrd.

I have introduced a new kernel commandline parameter, "qlang". If you put it into the kernel commandline in the boot-loader, say "qlang=fr", then the scripts in the initrd will automatically load the appropriate translation files.

If you don't have that "qlang" parameter, at the very first bootup the 'init' script will popup a dialog window:


...that is a compromise, as there is English text, and all the countries are the English names.

However, this dialog pops up early in the 'init' script, and immediately after, the script will load the appropriate language translation file. Well, it will do if one exists.

The GUI is only text-mode, using the 'dialog' utility. I do intend to have a more "proper" GUI sometime in the future. The 'dialog' utility is statically-linked, so standalone, requiring no libraries. See OE commit:

Here are the relevant woofQ commits:

If anyone is interested in creating some translation files, here are the files:

Note, the above photo shows a very complete list, but I will be reducing it considerably. I put in every language to start with, but most of those are unlikely to be required. Tibetan, for example, can go. I could probably look at all the translations offered by, say, LibreOffice, and reduce to those.

EDIT 2023-01-14:
There are 137 languages in that list. I have reduced it to 86, those languages offered by LibreOffice. Here they are:

af am ar as be bg bn bo br ca cs cy da de dz el en eo es et eu fa fi fr fy ga gd gl gu hi hr hu is it ja ka kk km kn ko ks lo lt lv mk ml mn mr my ne nl no oc om or pa pl pt ro ru rw sa sd si sk sl sq sr ss st sv sw ta te tg th tn tr ts tt uk uz vi xh zh zu

The Asian languages, such as Hindi, Japanese and Chinese, cannot be rendered in the initrd, so will stay at English. After bootup to the desktop, they will be offered, if suitable fonts are installed.

The problem in the initrd is the .psfu console fonts are only 256 characters, and only implement a small selection of unicode fonts. It is possible to get the full UTF-8 fonts working in the initrd, but that will have to be a future project.        

Tags: easy

EasyOS Dunfell-series version 4.5.5 released

January 10, 2023 — BarryK

Version 4.5.4 was released on January 4, and there has only been one bug-fix since then; however, I decided to release 4.5.5 as woofQ and EasyOS will be undergoing fundamental structural changes, for which it is better to start a new Series -- that will be the Kirkstone-series.

Hence, 4.5.5 is intended to be the last release of the Dunfell-series.

The "fundamental structural change" is mostly about international language support, and the previous couple of blog posts are about the start of that -- those changes are not in 4.5.5.

For more details, please read the announcement for 4.5:

And the follow-up bug-fix releases:

The release notes for 4.5.5:

Have fun!    

Tags: easy