Sample code to capture screen to memory (raw image) in Wayland

Hello,

is there some sample code to capture screen to memory (raw image). This codes should work on Gnome (Wayland) so cannot use any XWindow APIs. e.g. Firefox captures screen after asking user for permission.

earlier code :

auto y=g_dbus_connection_call_sync (connection,
“org.gnome.Shell.Screenshot”,
“/org/gnome/Shell/Screenshot”,
“org.gnome.Shell.Screenshot”,
“Screenshot”, …………

mimics screenshot and drops the content into a file….

You can use the XDG Desktop Portal API:

I did google that part:

auto y=g_dbus_connection_call_sync (connection,
                                     "org.freedesktop.portal.Screenshot",
                                     "/org/freedesktop/portal/Screenshot",
                                     "org.freedesktop.portal.Screenshot",
                                     "screenshot",
                                     g_variant_new ("parent_window"),  //no idea what to pass here
                                     NULL,
                                     G_DBUS_CALL_FLAGS_NONE,
                                     -1,
                                     NULL,
                                     &error);


is there any sample code for me to refer to…

GIMP uses the portal for screenshots for example:

There must be a signal for me to connect to which gives me the raw data:

e.g:

g_signal_connect(G_OBJECT(p), “ScreenShotReady”, G_CALLBACK(MyCallback), NULL);

There is a Response signal that contains a uri with the URI to an image file in its results. There is no raw data.

Thanks, this worked for me…now I want raw data …like what firefox gets when we give it screen recording access….

There is no API to get raw screenshot data.

how does firefox do this

Are you asking about screencasts (as in video) or screenshots (as in one static image)?

screen cast I guess: https://screen-recorder.com/
Also I will place the code here in the forum for others to follow.

For screen casts there is this portal:

Thanks, I will check, in the mean time, the below code I am using for future reference (it works fine on my Ubuntu 25.04 system)

//sudo apt install libgtk-4-dev
//gcc $(pkg-config --cflags gtk4) Wayland_screenShot.cpp $(pkg-config --libs gtk4) -lstdc++
//https://gitlab.gnome.org/GNOME/gimp/-/blob/2865aa7f039ee585e3c80d28d5ac75d0f8fef4e4/plug-ins/screenshot/screenshot-freedesktop.c

#include <bits/stdc++.h>
using namespace std;
#include <gtk/gtk.h>

GtkApplication *app=nullptr;
GMainLoop *main_loop=nullptr;
bool quitflag=false;

static void
screenshot_freedesktop_dbus_signal (GDBusProxy  *proxy,
gchar       *sender_name,
gchar       *signal_name,
GVariant    *parameters,
void  *image)
{
cout<<“inside screenshot_freedesktop_dbus_signal (1)”<<endl;

if (g_strcmp0 (signal_name, "Response") == 0)
{
    //got the screen shot
    cout<<"inside screenshot_freedesktop_dbus_signal (2)"<<endl;

    GVariant *results;
    guint32   response;
    g_variant_get (parameters, "(u@a{sv})",
                  &response,
                  &results);

    gchar *uri=nullptr;
    if (g_variant_lookup (results, "uri", "s", &uri))
    {
        cout<<uri<<endl;
    }
    g_free (uri);
    g_variant_unref (results);
}
g_main_loop_quit(main_loop);
//quitflag=true;
}

static void
activate (GtkApplication *app,
gpointer        user_data)
{
GDBusConnection \*connection;
g_autoptr(GError) error = NULL;

connection = g_application_get_dbus_connection (g_application_get_default ());

GDBusProxy *proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                      G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
                                      NULL,
                                      "org.freedesktop.portal.Desktop",
                                      "/org/freedesktop/portal/desktop",
                                      "org.freedesktop.portal.Screenshot",
                                      NULL, NULL);
{
    GVariant *retval1 = g_dbus_proxy_call_sync (proxy, "org.freedesktop.DBus.Peer.Ping",
                       NULL,
                       G_DBUS_CALL_FLAGS_NONE,
                       -1, NULL, &error);
    g_variant_unref (retval1);
}

GVariantBuilder *options = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
g_variant_builder_add (options, "{sv}", "interactive", g_variant_new_boolean (TRUE));

GVariant *retval=g_dbus_proxy_call_sync (proxy, "Screenshot",  //this will trigger the screen shot
                       g_variant_new ("(sa{sv})",
                                     "",
                                     options, NULL),
                       G_DBUS_CALL_FLAGS_NONE,
                       -1, NULL, &error);

if (retval)
{
    //now to get the request
    gchar *opath         = NULL;
    g_variant_get (retval, "(o)", &opath);
    auto proxy2 = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
                                       G_DBUS_PROXY_FLAGS_NONE,
                                       NULL,
                                       "org.freedesktop.portal.Desktop",
                                       opath,
                                       "org.freedesktop.portal.Request",
                                       NULL, NULL);


    g_signal_connect (proxy2, "g-signal",
                 G_CALLBACK (screenshot_freedesktop_dbus_signal),
                 nullptr);

    if(nullptr == main_loop)
        main_loop = g_main_loop_new (g_main_context_default(), TRUE);

    g_main_loop_run(main_loop);
    //while(false==quitflag)
    //    g_main_context_iteration (g_main_context_default(), TRUE);


    g_object_unref (proxy2);
    g_free (opath);

}

g_variant_unref (retval);
g_variant_builder_unref(options);
g_object_unref (proxy);
g_object_unref (connection);
}

int
main (int    argc,
char **argv)
{
int status;

app = gtk_application_new ("org.gnome.Screenshot", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);

g_main_loop_unref(main_loop);
g_object_unref (app);

return status;
}

Looking at Disable a dbus (the screenshot one) - #8 by wjt

I hope the screen shot application is now disabled in the newer versions of gnome.

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.