Add dummy backend
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
d702fc9365
commit
8eb9d07fa8
|
@ -10,13 +10,14 @@
|
||||||
#include "region.h"
|
#include "region.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
|
||||||
extern struct backend_operations xrender_ops;
|
extern struct backend_operations xrender_ops, dummy_ops;
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
extern struct backend_operations glx_ops;
|
extern struct backend_operations glx_ops;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct backend_operations *backend_list[NUM_BKEND] = {
|
struct backend_operations *backend_list[NUM_BKEND] = {
|
||||||
[BKEND_XRENDER] = &xrender_ops,
|
[BKEND_XRENDER] = &xrender_ops,
|
||||||
|
[BKEND_DUMMY] = &dummy_ops,
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
[BKEND_GLX] = &glx_ops,
|
[BKEND_GLX] = &glx_ops,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -225,8 +225,10 @@ struct backend_operations {
|
||||||
|
|
||||||
// =========== Hooks ============
|
// =========== Hooks ============
|
||||||
/// Let the backend hook into the event handling queue
|
/// Let the backend hook into the event handling queue
|
||||||
|
/// Not implemented yet
|
||||||
void (*set_ready_callback)(backend_t *, backend_ready_callback_t cb);
|
void (*set_ready_callback)(backend_t *, backend_ready_callback_t cb);
|
||||||
/// Called right after compton has handled its events.
|
/// Called right after compton has handled its events.
|
||||||
|
/// Not implemented yet
|
||||||
void (*handle_events)(backend_t *);
|
void (*handle_events)(backend_t *);
|
||||||
// =========== Misc ============
|
// =========== Misc ============
|
||||||
/// Return the driver that is been used by the backend
|
/// Return the driver that is been used by the backend
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
#include <uthash.h>
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
|
||||||
|
#include "backend/backend_common.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "compiler.h"
|
||||||
|
#include "uthash_extra.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
struct dummy_image {
|
||||||
|
xcb_pixmap_t pixmap;
|
||||||
|
bool transparent;
|
||||||
|
int refcount;
|
||||||
|
UT_hash_handle hh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dummy_data {
|
||||||
|
struct backend_base base;
|
||||||
|
struct dummy_image *images;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct backend_base *dummy_init(struct session *ps attr_unused) {
|
||||||
|
return (struct backend_base *)ccalloc(1, struct dummy_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_deinit(struct backend_base *data) {
|
||||||
|
auto dummy = (struct dummy_data *)data;
|
||||||
|
HASH_ITER2(dummy->images, img) {
|
||||||
|
log_warn("Backend image for pixmap %#010x is not freed", img->pixmap);
|
||||||
|
HASH_DEL(dummy->images, img);
|
||||||
|
free(img);
|
||||||
|
}
|
||||||
|
free(dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_compose(struct backend_base *base, void *image, int dst_x attr_unused,
|
||||||
|
int dst_y attr_unused, const region_t *reg_paint attr_unused,
|
||||||
|
const region_t *reg_visible attr_unused) {
|
||||||
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
auto img = (struct dummy_image *)image;
|
||||||
|
|
||||||
|
struct dummy_image *tmp = NULL;
|
||||||
|
HASH_FIND_INT(dummy->images, &img->pixmap, tmp);
|
||||||
|
if (!tmp) {
|
||||||
|
log_warn("Composing with an invalid (possibly freed) image");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_fill(struct backend_base *backend_data attr_unused, struct color c attr_unused,
|
||||||
|
const region_t *clip attr_unused) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dummy_blur(struct backend_base *backend_data attr_unused, double opacity attr_unused,
|
||||||
|
void *blur_ctx attr_unused, const region_t *reg_blur attr_unused,
|
||||||
|
const region_t *reg_visible attr_unused) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dummy_bind_pixmap(struct backend_base *base, xcb_pixmap_t pixmap,
|
||||||
|
struct xvisual_info fmt, bool owned attr_unused) {
|
||||||
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
struct dummy_image *img = NULL;
|
||||||
|
HASH_FIND_INT(dummy->images, &pixmap, img);
|
||||||
|
if (img) {
|
||||||
|
img->refcount++;
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
img = ccalloc(1, struct dummy_image);
|
||||||
|
img->pixmap = pixmap;
|
||||||
|
img->transparent = fmt.alpha_size != 0;
|
||||||
|
img->refcount = 1;
|
||||||
|
|
||||||
|
HASH_ADD_INT(dummy->images, pixmap, img);
|
||||||
|
return (void *)img;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_release_image(backend_t *base, void *image) {
|
||||||
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
auto img = (struct dummy_image *)image;
|
||||||
|
assert(img->refcount > 0);
|
||||||
|
img->refcount--;
|
||||||
|
if (img->refcount == 0) {
|
||||||
|
HASH_DEL(dummy->images, img);
|
||||||
|
free(img);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dummy_is_image_transparent(struct backend_base *base, void *image) {
|
||||||
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
auto img = (struct dummy_image *)image;
|
||||||
|
struct dummy_image *tmp = NULL;
|
||||||
|
HASH_FIND_INT(dummy->images, &img->pixmap, tmp);
|
||||||
|
if (!tmp) {
|
||||||
|
log_warn("Using an invalid (possibly freed) image");
|
||||||
|
}
|
||||||
|
return img->transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dummy_buffer_age(struct backend_base *base attr_unused) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool dummy_image_op(struct backend_base *base attr_unused, enum image_operations op attr_unused,
|
||||||
|
void *image attr_unused, const region_t *reg_op attr_unused,
|
||||||
|
const region_t *reg_visible attr_unused, void *args attr_unused) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dummy_image_copy(struct backend_base *base, const void *image,
|
||||||
|
const region_t *reg_visible attr_unused) {
|
||||||
|
auto dummy = (struct dummy_data *)base;
|
||||||
|
auto img = (struct dummy_image *)image;
|
||||||
|
struct dummy_image *tmp = NULL;
|
||||||
|
HASH_FIND_INT(dummy->images, &img->pixmap, tmp);
|
||||||
|
if (!tmp) {
|
||||||
|
log_warn("Using an invalid (possibly freed) image");
|
||||||
|
}
|
||||||
|
img->refcount++;
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *dummy_create_blur_context(struct backend_base *base attr_unused,
|
||||||
|
enum blur_method method attr_unused, void *args attr_unused) {
|
||||||
|
static int dummy_context;
|
||||||
|
return &dummy_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_destroy_blur_context(struct backend_base *base attr_unused, void *ctx attr_unused) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy_get_blur_size(void *ctx attr_unused, int *width, int *height) {
|
||||||
|
// These numbers are arbitrary, to make sure the reisze_region code path is
|
||||||
|
// covered.
|
||||||
|
*width = 5;
|
||||||
|
*height = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct backend_operations dummy_ops = {
|
||||||
|
.init = dummy_init,
|
||||||
|
.deinit = dummy_deinit,
|
||||||
|
.compose = dummy_compose,
|
||||||
|
.fill = dummy_fill,
|
||||||
|
.blur = dummy_blur,
|
||||||
|
.bind_pixmap = dummy_bind_pixmap,
|
||||||
|
.render_shadow = default_backend_render_shadow,
|
||||||
|
.release_image = dummy_release_image,
|
||||||
|
.is_image_transparent = dummy_is_image_transparent,
|
||||||
|
.buffer_age = dummy_buffer_age,
|
||||||
|
.max_buffer_age = 5,
|
||||||
|
|
||||||
|
.image_op = dummy_image_op,
|
||||||
|
.copy = dummy_image_copy,
|
||||||
|
.create_blur_context = dummy_create_blur_context,
|
||||||
|
.destroy_blur_context = dummy_destroy_blur_context,
|
||||||
|
.get_blur_size = dummy_get_blur_size,
|
||||||
|
|
||||||
|
};
|
|
@ -1,5 +1,5 @@
|
||||||
# enable xrender
|
# enable xrender
|
||||||
srcs += [ files('backend_common.c', 'xrender/xrender.c', 'backend.c', 'driver.c') ]
|
srcs += [ files('backend_common.c', 'xrender/xrender.c', 'dummy/dummy.c', 'backend.c', 'driver.c') ]
|
||||||
|
|
||||||
# enable opengl
|
# enable opengl
|
||||||
if get_option('opengl')
|
if get_option('opengl')
|
||||||
|
|
|
@ -80,10 +80,11 @@ const char *const WINTYPES[NUM_WINTYPES] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Names of backends.
|
/// Names of backends.
|
||||||
const char *const BACKEND_STRS[NUM_BKEND + 1] = {"xrender", // BKEND_XRENDER
|
const char *const BACKEND_STRS[] = {[BKEND_XRENDER] = "xrender",
|
||||||
"glx", // BKEND_GLX
|
[BKEND_GLX] = "glx",
|
||||||
"xr_glx_hybrid", // BKEND_XR_GLX_HYBRID
|
[BKEND_XR_GLX_HYBRID] = "xr_glx_hybrid",
|
||||||
NULL};
|
[BKEND_DUMMY] = "dummy",
|
||||||
|
NULL};
|
||||||
|
|
||||||
// === Global variables ===
|
// === Global variables ===
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ enum backend {
|
||||||
BKEND_XRENDER,
|
BKEND_XRENDER,
|
||||||
BKEND_GLX,
|
BKEND_GLX,
|
||||||
BKEND_XR_GLX_HYBRID,
|
BKEND_XR_GLX_HYBRID,
|
||||||
|
BKEND_DUMMY,
|
||||||
NUM_BKEND,
|
NUM_BKEND,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1087,6 +1087,10 @@ static bool init_alpha_picts(session_t *ps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_render(session_t *ps) {
|
bool init_render(session_t *ps) {
|
||||||
|
if (ps->o.backend == BKEND_DUMMY) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize OpenGL as early as possible
|
// Initialize OpenGL as early as possible
|
||||||
#ifdef CONFIG_OPENGL
|
#ifdef CONFIG_OPENGL
|
||||||
glxext_init(ps->dpy, ps->scr);
|
glxext_init(ps->dpy, ps->scr);
|
||||||
|
|
Loading…
Reference in New Issue