client.content: Return a cairo xcb surface

We no longer have to turn the client's content into an image buffer "by hand".
Instead, we can just use cairo for the job.

Even more exciting, we don't need to turn this into an image buffer at all. We
can just directly return a cairo xcb surface for the client window. Depending on
how lua will use this surface, this could make it possible to avoid having to
create the image buffer at all!

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2013-09-16 12:09:40 +02:00
parent 11bef0795a
commit 813fb94ce8
1 changed files with 12 additions and 26 deletions

View File

@ -1789,43 +1789,29 @@ LUA_OBJECT_EXPORT_PROPERTY(client, client_t, maximized_vertical, lua_pushboolean
static int static int
luaA_client_get_content(lua_State *L, client_t *c) luaA_client_get_content(lua_State *L, client_t *c)
{ {
xcb_image_t *ximage; xcb_get_window_attributes_cookie_t cookie;
xcb_get_window_attributes_reply_t *attr;
cairo_surface_t *surface;
int width = c->geometry.width; int width = c->geometry.width;
int height = c->geometry.height; int height = c->geometry.height;
/* Just the client size without decorations */
width -= c->titlebar[CLIENT_TITLEBAR_LEFT].size + c->titlebar[CLIENT_TITLEBAR_RIGHT].size; width -= c->titlebar[CLIENT_TITLEBAR_LEFT].size + c->titlebar[CLIENT_TITLEBAR_RIGHT].size;
height -= c->titlebar[CLIENT_TITLEBAR_TOP].size + c->titlebar[CLIENT_TITLEBAR_BOTTOM].size; height -= c->titlebar[CLIENT_TITLEBAR_TOP].size + c->titlebar[CLIENT_TITLEBAR_BOTTOM].size;
ximage = xcb_image_get(globalconf.connection,
c->window,
0, 0,
width, height,
~0, XCB_IMAGE_FORMAT_Z_PIXMAP);
cairo_surface_t *surface = NULL;
if(ximage) cookie = xcb_get_window_attributes(globalconf.connection, c->window);
{ attr = xcb_get_window_attributes_reply(globalconf.connection, cookie, NULL);
if(ximage->bpp >= 24)
{
uint32_t *data = p_new(uint32_t, ximage->width * ximage->height);
for(int y = 0; y < ximage->height; y++) if (!attr)
for(int x = 0; x < ximage->width; x++)
{
data[y * ximage->width + x] = xcb_image_get_pixel(ximage, x, y);
data[y * ximage->width + x] |= 0xff000000; /* set alpha to 0xff */
}
surface = draw_surface_from_data(ximage->width, ximage->height, data);
p_delete(&data);
}
xcb_image_destroy(ximage);
}
if (!surface)
return 0; return 0;
surface = cairo_xcb_surface_create(globalconf.connection, c->window,
draw_find_visual(globalconf.screen, attr->visual),
width, height);
/* lua has to make sure to free the ref or we have a leak */ /* lua has to make sure to free the ref or we have a leak */
lua_pushlightuserdata(L, surface); lua_pushlightuserdata(L, surface);
free(attr);
return 1; return 1;
} }