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 a interlaced image with true colors. The component also requires a ROM session that is used as a trigger and must contain valid XML. 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 my goa-pkgs repository.

Usage

The screenshot component is provided by the jschlatow/pkg/screenshot package. This package requires four session: 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 the system GUI. For the File_system session, you can choose the recall_fs or any other writeable file system.

Before being able to enjoy the new ease of taking screenshots on key presses, you must register KEY_PRINT as a global key. This is done in /config/nitpicker with the following line:

 <global-key name="KEY_PRINT" label="runtime -> screenshot -> keys -> input" />

I believe the label needs a bit of an explanation: runtime stands for the runtime subsystem, 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.

As a last step, edit your /config/event_filter to remap a key of your liking to KEY_PRINT, let’s say F11:

 <remap>
     <key name="KEY_F11" to="KEY_PRINT"/>
     [...]
 </remap>

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

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

Note, in Sculpt 21.03b, you must manually add my depot files. You can take the download and pubkey files from this pull request.

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.