Site logo
Stories around the Genode Operating System RSS feed
Johannes Schlatow avatar

Native screenshot component


Martin had recently expressed to me that a native screenshot component using the Capture session would be really helpful. Moreover, when writing the VNC server article, I also encountered the need to make a screenshot myself. As I already got in touch with the Capture session, I briefly switched contexts to bring the screenshot component into being right away.

First of all, let me start with the facts: The screenshot component uses the libpng port for creating a png file from the Capture data. More precisely, it creates an interlaced image with true colors. The component also requires a ROM session that is used as a trigger. Whenever the ROM changes, it looks whether the root node has an enabled: yes attribute. This is aligned with the reports generated by the global_keys_handler component. If the attribute is present, it takes the root node's tag and the current data/time (from an Rtc session) to generate a filename.

You can find the source files for this package in the genode-world repository.

Usage

The screenshot component is provided by the jschlatow/pkg/screenshot package. This package requires four sessions: a Gui session, a Capture session, a File_system session and an Rtc session. The Gui session is required for receiving key events, which are processed by the package’s global_keys_handler that updates the report on presses/releases of KEY_PRINT. Both, the Gui and Capture session, must be routed to "gui". For the File_system session, you can choose the recall_fs or any other writeable file system.

The default config of the gui child at /model/child/gui contains the following rule to register KEY_PRINT as a global key:

 + global-key KEY_PRINT | label: screenshot -> keys -> input

I believe the label needs a bit of an explanation: screenshot is the name of the deployed screenshot sub-init, keys refers to the name of the global_keys_handler started by screenshot’s sub-init, and input is the Gui session label used by the global_keys_handler.

Depending on the keyboard you are using, you might want to remap a key of your liking to KEY_PRINT, let's say F11, by editing /model/child/event_filter and by adding a key node inside the remap node:

 + remap
   + key KEY_11 | to: KEY_PRINT

Now, press F11 and have a look at your log:

 [runtime -> screenshot -> screenshot] Writing screenshot to screenshot_2021-6-9 13:16:3.png

Side effect: More Goa extensions

Implementing the screenshot component also turned out to pay off for Goa. I extended Goa to support rtc requirements to be able to run and test the screenshot component in Goa.

Moreover, when I first tried to build the screenshot component with Goa, I faced the following error:

 [...]/depot/nfeske/api/libc/2021-02-22/include/libc/x86/_types.h:106:9:
  error: declaration does not declare anything [-fpermissive]
  typedef __SIZE_TYPE__ __size_t;  /* sizeof() */

Yikes! What’s that? Apparently, libc tried to redeclare __size_t. After a little digging, I found out that the import-libc.mk in the Genode repository fixes this issue by setting CC_OPT += -D__FreeBSD__=12. By replicating this in Goa’s quirks.tcl, this issue should be a matter of the past.

Edit 2025-05-04: Updated instructions for Sculpt 26.04