forked from external/yambar
bar: don't use cairo
This is trivial in the Wayland backend; just instantiate a pixman pointing to the same mmapped memory as the wayland buffer. In the XCB backend, we change the implementation slightly; instead of rendering via a cairo XCB surface backend (to a server side pixmap), which is then blitted to the window in commit(), we now render to a client-side pixman pixmap, and blit it using xcb_put_image() in commit().
This commit is contained in:
parent
c11fee4ce3
commit
01e71590e0
5 changed files with 58 additions and 156 deletions
|
@ -11,8 +11,7 @@ struct backend {
|
||||||
void (*expose)(const struct bar *bar),
|
void (*expose)(const struct bar *bar),
|
||||||
void (*on_mouse)(struct bar *bar, enum mouse_event event,
|
void (*on_mouse)(struct bar *bar, enum mouse_event event,
|
||||||
int x, int y));
|
int x, int y));
|
||||||
pixman_image_t *(*get_pixman_image)(const struct bar *bar);
|
void (*commit)(const struct bar *bar);
|
||||||
void (*commit_pixman)(const struct bar *bar, pixman_image_t *pix);
|
|
||||||
void (*refresh)(const struct bar *bar);
|
void (*refresh)(const struct bar *bar);
|
||||||
void (*set_cursor)(struct bar *bar, const char *cursor);
|
void (*set_cursor)(struct bar *bar, const char *cursor);
|
||||||
};
|
};
|
||||||
|
|
14
bar/bar.c
14
bar/bar.c
|
@ -61,7 +61,7 @@ static void
|
||||||
expose(const struct bar *_bar)
|
expose(const struct bar *_bar)
|
||||||
{
|
{
|
||||||
const struct private *bar = _bar->private;
|
const struct private *bar = _bar->private;
|
||||||
pixman_image_t *pix = bar->backend.iface->get_pixman_image(_bar);
|
pixman_image_t *pix = bar->pix;
|
||||||
|
|
||||||
pixman_image_fill_rectangles(
|
pixman_image_fill_rectangles(
|
||||||
PIXMAN_OP_SRC, pix, &bar->background, 1,
|
PIXMAN_OP_SRC, pix, &bar->background, 1,
|
||||||
|
@ -138,7 +138,7 @@ expose(const struct bar *_bar)
|
||||||
x += bar->left_spacing + e->width + bar->right_spacing;
|
x += bar->left_spacing + e->width + bar->right_spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
bar->backend.iface->commit_pixman(_bar, pix);
|
bar->backend.iface->commit(_bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -299,14 +299,6 @@ run(struct bar *_bar)
|
||||||
|
|
||||||
bar->backend.iface->cleanup(_bar);
|
bar->backend.iface->cleanup(_bar);
|
||||||
|
|
||||||
if (bar->cairo)
|
|
||||||
cairo_destroy(bar->cairo);
|
|
||||||
if (bar->cairo_surface) {
|
|
||||||
cairo_device_finish(cairo_surface_get_device(bar->cairo_surface));
|
|
||||||
cairo_surface_finish(bar->cairo_surface);
|
|
||||||
cairo_surface_destroy(bar->cairo_surface);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DBG("bar exiting");
|
LOG_DBG("bar exiting");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -341,8 +333,6 @@ destroy(struct bar *bar)
|
||||||
m->destroy(m);
|
m->destroy(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_debug_reset_static_data();
|
|
||||||
|
|
||||||
free(b->left.mods);
|
free(b->left.mods);
|
||||||
free(b->left.exps);
|
free(b->left.exps);
|
||||||
free(b->center.mods);
|
free(b->center.mods);
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cairo.h>
|
|
||||||
#include <cairo-xcb.h>
|
|
||||||
|
|
||||||
#include "../bar/bar.h"
|
#include "../bar/bar.h"
|
||||||
#include "backend.h"
|
#include "backend.h"
|
||||||
|
|
||||||
|
@ -46,22 +43,10 @@ struct private {
|
||||||
/* Name of currently active cursor */
|
/* Name of currently active cursor */
|
||||||
char *cursor_name;
|
char *cursor_name;
|
||||||
|
|
||||||
cairo_t *cairo;
|
pixman_image_t *pix;
|
||||||
cairo_surface_t *cairo_surface;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void *data;
|
void *data;
|
||||||
const struct backend *iface;
|
const struct backend *iface;
|
||||||
} backend;
|
} backend;
|
||||||
#if 0
|
|
||||||
/* Backend specifics */
|
|
||||||
xcb_connection_t *conn;
|
|
||||||
|
|
||||||
xcb_window_t win;
|
|
||||||
xcb_colormap_t colormap;
|
|
||||||
xcb_pixmap_t pixmap;
|
|
||||||
xcb_gc_t gc;
|
|
||||||
xcb_cursor_context_t *cursor_ctx;
|
|
||||||
xcb_cursor_t cursor;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <linux/memfd.h>
|
#include <linux/memfd.h>
|
||||||
|
|
||||||
#include <cairo.h>
|
//#include <cairo.h>
|
||||||
|
#include <pixman.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <wayland-cursor.h>
|
#include <wayland-cursor.h>
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
#define LOG_ENABLE_DBG 0
|
#define LOG_ENABLE_DBG 0
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
#include "../tllist.h"
|
#include "../tllist.h"
|
||||||
|
#include "../stride.h"
|
||||||
|
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
|
@ -31,8 +33,7 @@ struct buffer {
|
||||||
|
|
||||||
struct wl_buffer *wl_buf;
|
struct wl_buffer *wl_buf;
|
||||||
|
|
||||||
cairo_surface_t *cairo_surface;
|
pixman_image_t *pix;
|
||||||
cairo_t *cairo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct monitor {
|
struct monitor {
|
||||||
|
@ -448,11 +449,10 @@ get_buffer(struct wayland_backend *backend)
|
||||||
* No existing buffer available. Create a new one by:
|
* No existing buffer available. Create a new one by:
|
||||||
*
|
*
|
||||||
* 1. open a memory backed "file" with memfd_create()
|
* 1. open a memory backed "file" with memfd_create()
|
||||||
* 2. mmap() the memory file, to be used by the cairo surface
|
* 2. mmap() the memory file, to be used by the pixman image
|
||||||
* 3. create a wayland shm buffer for the same memory file
|
* 3. create a wayland shm buffer for the same memory file
|
||||||
*
|
*
|
||||||
* The cairo surface and the wayland buffer are now sharing
|
* The pixman image and the wayland buffer are now sharing memory.
|
||||||
* memory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int pool_fd = -1;
|
int pool_fd = -1;
|
||||||
|
@ -462,8 +462,7 @@ get_buffer(struct wayland_backend *backend)
|
||||||
struct wl_shm_pool *pool = NULL;
|
struct wl_shm_pool *pool = NULL;
|
||||||
struct wl_buffer *buf = NULL;
|
struct wl_buffer *buf = NULL;
|
||||||
|
|
||||||
cairo_surface_t *cairo_surface = NULL;
|
pixman_image_t *pix = NULL;
|
||||||
cairo_t *cairo = NULL;
|
|
||||||
|
|
||||||
/* Backing memory for SHM */
|
/* Backing memory for SHM */
|
||||||
pool_fd = memfd_create("f00bar-wayland-shm-buffer-pool", MFD_CLOEXEC);
|
pool_fd = memfd_create("f00bar-wayland-shm-buffer-pool", MFD_CLOEXEC);
|
||||||
|
@ -473,8 +472,9 @@ get_buffer(struct wayland_backend *backend)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Total size */
|
/* Total size */
|
||||||
const uint32_t stride = cairo_format_stride_for_width(
|
const uint32_t stride = stride_for_format_and_width(
|
||||||
CAIRO_FORMAT_ARGB32, backend->width);
|
PIXMAN_a8r8g8b8, backend->width);
|
||||||
|
|
||||||
size = stride * backend->height;
|
size = stride * backend->height;
|
||||||
if (ftruncate(pool_fd, size) == -1) {
|
if (ftruncate(pool_fd, size) == -1) {
|
||||||
LOG_ERR("failed to truncate SHM pool");
|
LOG_ERR("failed to truncate SHM pool");
|
||||||
|
@ -504,19 +504,10 @@ get_buffer(struct wayland_backend *backend)
|
||||||
wl_shm_pool_destroy(pool); pool = NULL;
|
wl_shm_pool_destroy(pool); pool = NULL;
|
||||||
close(pool_fd); pool_fd = -1;
|
close(pool_fd); pool_fd = -1;
|
||||||
|
|
||||||
/* Create a cairo surface around the mmapped memory */
|
pix = pixman_image_create_bits_no_clear(
|
||||||
cairo_surface = cairo_image_surface_create_for_data(
|
PIXMAN_a8r8g8b8, backend->width, backend->height, (uint32_t *)mmapped, stride);
|
||||||
mmapped, CAIRO_FORMAT_ARGB32, backend->width, backend->height, stride);
|
if (pix == NULL) {
|
||||||
if (cairo_surface_status(cairo_surface) != CAIRO_STATUS_SUCCESS) {
|
LOG_ERR("failed to create pixman image");
|
||||||
LOG_ERR("failed to create cairo surface: %s",
|
|
||||||
cairo_status_to_string(cairo_surface_status(cairo_surface)));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo = cairo_create(cairo_surface);
|
|
||||||
if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS) {
|
|
||||||
LOG_ERR("failed to create cairo context: %s",
|
|
||||||
cairo_status_to_string(cairo_status(cairo)));
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,9 +519,8 @@ get_buffer(struct wayland_backend *backend)
|
||||||
.size = size,
|
.size = size,
|
||||||
.mmapped = mmapped,
|
.mmapped = mmapped,
|
||||||
.wl_buf = buf,
|
.wl_buf = buf,
|
||||||
.cairo_surface = cairo_surface,
|
.pix = pix,
|
||||||
.cairo = cairo}
|
})
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
struct buffer *ret = &tll_back(backend->buffers);
|
struct buffer *ret = &tll_back(backend->buffers);
|
||||||
|
@ -538,10 +528,8 @@ get_buffer(struct wayland_backend *backend)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (cairo != NULL)
|
if (pix != NULL)
|
||||||
cairo_destroy(cairo);
|
pixman_image_unref(pix);
|
||||||
if (cairo_surface != NULL)
|
|
||||||
cairo_surface_destroy(cairo_surface);
|
|
||||||
if (buf != NULL)
|
if (buf != NULL)
|
||||||
wl_buffer_destroy(buf);
|
wl_buffer_destroy(buf);
|
||||||
if (pool != NULL)
|
if (pool != NULL)
|
||||||
|
@ -712,9 +700,7 @@ setup(struct bar *_bar)
|
||||||
/* Prepare a buffer + cairo context for bar to draw to */
|
/* Prepare a buffer + cairo context for bar to draw to */
|
||||||
backend->next_buffer = get_buffer(backend);
|
backend->next_buffer = get_buffer(backend);
|
||||||
assert(backend->next_buffer != NULL && backend->next_buffer->busy);
|
assert(backend->next_buffer != NULL && backend->next_buffer->busy);
|
||||||
|
bar->pix = backend->next_buffer->pix;
|
||||||
bar->cairo_surface = backend->next_buffer->cairo_surface;
|
|
||||||
bar->cairo = backend->next_buffer->cairo;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -728,10 +714,8 @@ cleanup(struct bar *_bar)
|
||||||
tll_foreach(backend->buffers, it) {
|
tll_foreach(backend->buffers, it) {
|
||||||
if (it->item.wl_buf != NULL)
|
if (it->item.wl_buf != NULL)
|
||||||
wl_buffer_destroy(it->item.wl_buf);
|
wl_buffer_destroy(it->item.wl_buf);
|
||||||
if (it->item.cairo != NULL)
|
if (it->item.pix != NULL)
|
||||||
cairo_destroy(it->item.cairo);
|
pixman_image_unref(it->item.pix);
|
||||||
if (it->item.cairo_surface != NULL)
|
|
||||||
cairo_surface_destroy(it->item.cairo_surface);
|
|
||||||
|
|
||||||
munmap(it->item.mmapped, it->item.size);
|
munmap(it->item.mmapped, it->item.size);
|
||||||
tll_remove(backend->buffers, it);
|
tll_remove(backend->buffers, it);
|
||||||
|
@ -778,8 +762,7 @@ cleanup(struct bar *_bar)
|
||||||
wl_display_disconnect(backend->display);
|
wl_display_disconnect(backend->display);
|
||||||
|
|
||||||
/* Destroyed when freeing buffer list */
|
/* Destroyed when freeing buffer list */
|
||||||
bar->cairo_surface = NULL;
|
bar->pix = NULL;
|
||||||
bar->cairo = NULL;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -901,31 +884,12 @@ frame_callback(void *data, struct wl_callback *wl_callback, uint32_t callback_da
|
||||||
;//printf("nothing more to do\n");
|
;//printf("nothing more to do\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static pixman_image_t *
|
|
||||||
get_pixman_image(const struct bar *_bar)
|
|
||||||
{
|
|
||||||
struct private *bar = _bar->private;
|
|
||||||
|
|
||||||
cairo_surface_t *surf = cairo_get_target(bar->cairo);
|
|
||||||
cairo_surface_flush(surf);
|
|
||||||
|
|
||||||
return pixman_image_create_bits_no_clear(
|
|
||||||
PIXMAN_a8r8g8b8,
|
|
||||||
cairo_image_surface_get_width(surf),
|
|
||||||
cairo_image_surface_get_height(surf),
|
|
||||||
(uint32_t *)cairo_image_surface_get_data(surf),
|
|
||||||
cairo_image_surface_get_stride(surf));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
commit_pixman(const struct bar *_bar, pixman_image_t *pix)
|
commit(const struct bar *_bar)
|
||||||
{
|
{
|
||||||
struct private *bar = _bar->private;
|
struct private *bar = _bar->private;
|
||||||
struct wayland_backend *backend = bar->backend.data;
|
struct wayland_backend *backend = bar->backend.data;
|
||||||
|
|
||||||
pixman_image_unref(pix);
|
|
||||||
cairo_surface_mark_dirty(cairo_get_target(bar->cairo));
|
|
||||||
|
|
||||||
//printf("commit: %dxl%d\n", backend->width, backend->height);
|
//printf("commit: %dxl%d\n", backend->width, backend->height);
|
||||||
|
|
||||||
assert(backend->next_buffer != NULL);
|
assert(backend->next_buffer != NULL);
|
||||||
|
@ -958,9 +922,7 @@ commit_pixman(const struct bar *_bar, pixman_image_t *pix)
|
||||||
|
|
||||||
backend->next_buffer = get_buffer(backend);
|
backend->next_buffer = get_buffer(backend);
|
||||||
assert(backend->next_buffer != NULL && backend->next_buffer->busy);
|
assert(backend->next_buffer != NULL && backend->next_buffer->busy);
|
||||||
|
bar->pix = backend->next_buffer->pix;
|
||||||
bar->cairo_surface = backend->next_buffer->cairo_surface;
|
|
||||||
bar->cairo = backend->next_buffer->cairo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -992,8 +954,7 @@ const struct backend wayland_backend_iface = {
|
||||||
.setup = &setup,
|
.setup = &setup,
|
||||||
.cleanup = &cleanup,
|
.cleanup = &cleanup,
|
||||||
.loop = &loop,
|
.loop = &loop,
|
||||||
.get_pixman_image = &get_pixman_image,
|
.commit = &commit,
|
||||||
.commit_pixman = &commit_pixman,
|
|
||||||
.refresh = &refresh,
|
.refresh = &refresh,
|
||||||
.set_cursor = &set_cursor,
|
.set_cursor = &set_cursor,
|
||||||
};
|
};
|
||||||
|
|
91
bar/xcb.c
91
bar/xcb.c
|
@ -6,6 +6,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
|
#include <pixman.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
|
|
||||||
#define LOG_MODULE "bar:xcb"
|
#define LOG_MODULE "bar:xcb"
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
|
#include "../stride.h"
|
||||||
#include "../xcb.h"
|
#include "../xcb.h"
|
||||||
|
|
||||||
struct xcb_backend {
|
struct xcb_backend {
|
||||||
|
@ -27,10 +29,15 @@ struct xcb_backend {
|
||||||
|
|
||||||
xcb_window_t win;
|
xcb_window_t win;
|
||||||
xcb_colormap_t colormap;
|
xcb_colormap_t colormap;
|
||||||
xcb_pixmap_t pixmap;
|
|
||||||
xcb_gc_t gc;
|
xcb_gc_t gc;
|
||||||
xcb_cursor_context_t *cursor_ctx;
|
xcb_cursor_context_t *cursor_ctx;
|
||||||
xcb_cursor_t cursor;
|
xcb_cursor_t cursor;
|
||||||
|
|
||||||
|
uint8_t depth;
|
||||||
|
void *client_pixmap;
|
||||||
|
size_t client_pixmap_size;
|
||||||
|
pixman_image_t *pix;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
@ -131,6 +138,7 @@ setup(struct bar *_bar)
|
||||||
|
|
||||||
assert(depth == 32 || depth == 24);
|
assert(depth == 32 || depth == 24);
|
||||||
assert(vis != NULL);
|
assert(vis != NULL);
|
||||||
|
backend->depth = depth;
|
||||||
LOG_DBG("using a %hhu-bit visual", depth);
|
LOG_DBG("using a %hhu-bit visual", depth);
|
||||||
|
|
||||||
backend->colormap = xcb_generate_id(backend->conn);
|
backend->colormap = xcb_generate_id(backend->conn);
|
||||||
|
@ -234,19 +242,20 @@ setup(struct bar *_bar)
|
||||||
_NET_WM_STRUT_PARTIAL, XCB_ATOM_CARDINAL, 32,
|
_NET_WM_STRUT_PARTIAL, XCB_ATOM_CARDINAL, 32,
|
||||||
12, strut);
|
12, strut);
|
||||||
|
|
||||||
backend->pixmap = xcb_generate_id(backend->conn);
|
|
||||||
xcb_create_pixmap(backend->conn, depth, backend->pixmap, backend->win,
|
|
||||||
bar->width, bar->height_with_border);
|
|
||||||
|
|
||||||
backend->gc = xcb_generate_id(backend->conn);
|
backend->gc = xcb_generate_id(backend->conn);
|
||||||
xcb_create_gc(backend->conn, backend->gc, backend->pixmap,
|
xcb_create_gc(backend->conn, backend->gc, backend->win,
|
||||||
XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES,
|
XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES,
|
||||||
(const uint32_t []){screen->white_pixel, 0});
|
(const uint32_t []){screen->white_pixel, 0});
|
||||||
|
|
||||||
LOG_DBG("cairo: %s", cairo_version_string());
|
const uint32_t stride = stride_for_format_and_width(
|
||||||
bar->cairo_surface = cairo_xcb_surface_create(
|
PIXMAN_a8r8g8b8, bar->width);
|
||||||
backend->conn, backend->pixmap, vis, bar->width, bar->height_with_border);
|
|
||||||
bar->cairo = cairo_create(bar->cairo_surface);
|
backend->client_pixmap_size = stride * bar->height_with_border;
|
||||||
|
backend->client_pixmap = malloc(backend->client_pixmap_size);
|
||||||
|
backend->pix = pixman_image_create_bits_no_clear(
|
||||||
|
PIXMAN_a8r8g8b8, bar->width, bar->height_with_border,
|
||||||
|
(uint32_t *)backend->client_pixmap, stride);
|
||||||
|
bar->pix = backend->pix;
|
||||||
|
|
||||||
xcb_map_window(backend->conn, backend->win);
|
xcb_map_window(backend->conn, backend->win);
|
||||||
|
|
||||||
|
@ -274,10 +283,12 @@ cleanup(struct bar *_bar)
|
||||||
/* TODO: move to bar.c */
|
/* TODO: move to bar.c */
|
||||||
free(bar->cursor_name);
|
free(bar->cursor_name);
|
||||||
|
|
||||||
|
if (backend->pix != NULL)
|
||||||
|
pixman_image_unref(backend->pix);
|
||||||
|
free(backend->client_pixmap);
|
||||||
|
|
||||||
if (backend->gc != 0)
|
if (backend->gc != 0)
|
||||||
xcb_free_gc(backend->conn, backend->gc);
|
xcb_free_gc(backend->conn, backend->gc);
|
||||||
if (backend->pixmap != 0)
|
|
||||||
xcb_free_pixmap(backend->conn, backend->pixmap);
|
|
||||||
if (backend->win != 0)
|
if (backend->win != 0)
|
||||||
xcb_destroy_window(backend->conn, backend->win);
|
xcb_destroy_window(backend->conn, backend->win);
|
||||||
if (backend->colormap != 0)
|
if (backend->colormap != 0)
|
||||||
|
@ -370,58 +381,15 @@ loop(struct bar *_bar,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_pixman_bits(pixman_image_t *pix, void *data)
|
commit(const struct bar *_bar)
|
||||||
{
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static pixman_image_t *
|
|
||||||
get_pixman_image(const struct bar *_bar)
|
|
||||||
{
|
|
||||||
const struct private *bar = _bar->private;
|
|
||||||
uint32_t *bits = malloc(
|
|
||||||
bar->width * bar->height_with_border * sizeof(uint32_t));
|
|
||||||
|
|
||||||
pixman_image_t *ret = pixman_image_create_bits_no_clear(
|
|
||||||
PIXMAN_a8r8g8b8,
|
|
||||||
bar->width,
|
|
||||||
bar->height_with_border,
|
|
||||||
bits,
|
|
||||||
bar->width * sizeof(uint32_t));
|
|
||||||
|
|
||||||
if (ret == NULL) {
|
|
||||||
free(bits);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixman_image_set_destroy_function(ret, &free_pixman_bits, bits);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
commit_pixman(const struct bar *_bar, pixman_image_t *pix)
|
|
||||||
{
|
{
|
||||||
const struct private *bar = _bar->private;
|
const struct private *bar = _bar->private;
|
||||||
const struct xcb_backend *backend = bar->backend.data;
|
const struct xcb_backend *backend = bar->backend.data;
|
||||||
|
|
||||||
/* Blit pixman image to our XCB surface */
|
xcb_put_image(
|
||||||
cairo_surface_t *surf = cairo_image_surface_create_for_data(
|
backend->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, backend->win, backend->gc,
|
||||||
(unsigned char *)pixman_image_get_data(pix),
|
bar->width, bar->height_with_border, 0, 0, 0,
|
||||||
CAIRO_FORMAT_ARGB32,
|
backend->depth, backend->client_pixmap_size, backend->client_pixmap);
|
||||||
bar->width,
|
|
||||||
bar->height_with_border,
|
|
||||||
cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, bar->width));
|
|
||||||
|
|
||||||
cairo_set_source_surface(bar->cairo, surf, 0, 0);
|
|
||||||
cairo_set_operator(bar->cairo, CAIRO_OPERATOR_SOURCE);
|
|
||||||
cairo_paint(bar->cairo);
|
|
||||||
|
|
||||||
cairo_surface_flush(bar->cairo_surface);
|
|
||||||
cairo_surface_destroy(surf);
|
|
||||||
pixman_image_unref(pix);
|
|
||||||
|
|
||||||
xcb_copy_area(backend->conn, backend->pixmap, backend->win, backend->gc,
|
|
||||||
0, 0, 0, 0, bar->width, bar->height_with_border);
|
|
||||||
xcb_flush(backend->conn);
|
xcb_flush(backend->conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,8 +444,7 @@ const struct backend xcb_backend_iface = {
|
||||||
.setup = &setup,
|
.setup = &setup,
|
||||||
.cleanup = &cleanup,
|
.cleanup = &cleanup,
|
||||||
.loop = &loop,
|
.loop = &loop,
|
||||||
.get_pixman_image = &get_pixman_image,
|
.commit = &commit,
|
||||||
.commit_pixman = &commit_pixman,
|
|
||||||
.refresh = &refresh,
|
.refresh = &refresh,
|
||||||
.set_cursor = &set_cursor,
|
.set_cursor = &set_cursor,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue