From f6eef228e247a2105538cef7a45d4cc76632d809 Mon Sep 17 00:00:00 2001 From: Brian Sobulefsky Date: Mon, 27 Sep 2021 08:29:50 -0700 Subject: [PATCH] Updated API in the same interface as the client.content property to support screenshots at the root window and screen levels. A call to the root.content() method will return a screenshot as a Cairo surface of the entire root window (generally all physical screens). Getting the screen.content property will return a screenshot as a Cairo surface of the screen object (generally a physical screen) just as client.content will for a client object. Sample usage - the traditional API supported focused client screenshot as: c = client.focus if c then gears.surface(c.content):write_to_png("/path/to/screenshot.png") end Similarly, this API extension adds: s = awful.screen.focused() if s then gears.surface(s.content):write_to_png("/path/to/screenshot.png") end for the screen class and: gears.surface(root.content()):write_to_png("/path/to/screenshot.png") for the root window. Note that the example shows how to get a screenshot of the focused screen, but this is not a limitation. A lua script could call it on any screen object. Signed off by Brian Sobulefsky --- objects/screen.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ root.c | 26 +++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/objects/screen.c b/objects/screen.c index 5fd2b501b..79b036d99 100644 --- a/objects/screen.c +++ b/objects/screen.c @@ -59,6 +59,9 @@ #include #include +#include +#include + /* The XID that is used on fake screens. X11 guarantees that the top three bits * of a valid XID are zero, so this will not clash with anything. */ @@ -1655,6 +1658,60 @@ luaA_screen_get_name(lua_State *L, screen_t *s) return 1; } +/** Get the content of the active screen as a cairo surface + * + * @return A cairo surface + * @staticfct content + */ +static int +luaA_screen_get_content(lua_State *L, screen_t *s) +{ + + cairo_surface_t *root_surface; + cairo_surface_t *scrn_surface; + cairo_t *scrn_cr; + + area_t *scrn_geom; + + int root_width = globalconf.screen->width_in_pixels; + int root_height = globalconf.screen->height_in_pixels; + + scrn_geom = &(s->geometry); + + root_surface = cairo_xcb_surface_create(globalconf.connection, + globalconf.screen->root, + globalconf.default_visual, + root_width, root_height); + + scrn_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + scrn_geom->width, scrn_geom->height); + scrn_cr = cairo_create(scrn_surface); + + if(cairo_surface_status(root_surface) != CAIRO_STATUS_SUCCESS || + cairo_surface_status(scrn_surface) != CAIRO_STATUS_SUCCESS){ + cairo_surface_destroy(root_surface); + cairo_surface_destroy(scrn_surface); + cairo_destroy(scrn_cr); + return 0; + } + + cairo_set_source_surface(scrn_cr, root_surface, + -(scrn_geom->x), -(scrn_geom->y)); + cairo_rectangle(scrn_cr, 0, 0, scrn_geom->width, scrn_geom->height); + cairo_fill(scrn_cr); + + cairo_surface_destroy(root_surface); + cairo_destroy(scrn_cr); + + lua_pushlightuserdata(L, scrn_surface); + + return 1; + +} + + + + /** Get the number of screens. * * @return The screen count, at least 1. @@ -1902,6 +1959,10 @@ screen_class_setup(lua_State *L) (lua_class_propfunc_t) luaA_screen_set_name, (lua_class_propfunc_t) luaA_screen_get_name, (lua_class_propfunc_t) luaA_screen_set_name); + luaA_class_add_property(&screen_class, "content", + NULL, + (lua_class_propfunc_t) luaA_screen_get_content, + NULL); } /* @DOC_cobject_COMMON@ */ diff --git a/root.c b/root.c index 4b5ebfbed..822fa01c8 100644 --- a/root.c +++ b/root.c @@ -500,6 +500,31 @@ luaA_root_wallpaper(lua_State *L) return 1; } + +/** Get the content of the root window as a cairo surface + * + * @return A cairo surface + * @staticfct content + */ +static int +luaA_root_get_content(lua_State *L) +{ + + cairo_surface_t *surface; + int width = globalconf.screen->width_in_pixels; + int height = globalconf.screen->height_in_pixels; + + surface = cairo_xcb_surface_create(globalconf.connection, + globalconf.screen->root, + globalconf.default_visual, + width, height); + + lua_pushlightuserdata(L, surface); + return 1; + +} + + /** Get the size of the root window. * * @return Width of the root window. @@ -608,6 +633,7 @@ const struct luaL_Reg awesome_root_methods[] = { "fake_input", luaA_root_fake_input }, { "drawins", luaA_root_drawins }, { "_wallpaper", luaA_root_wallpaper }, + { "content", luaA_root_get_content}, { "size", luaA_root_size }, { "size_mm", luaA_root_size_mm }, { "tags", luaA_root_tags },