Allow compositor to load Cairo backend later at runtime

This commit is contained in:
K. Lange 2018-10-02 18:58:03 +09:00
parent 1a9a00e574
commit 719d27166d
6 changed files with 55 additions and 16 deletions

View File

@ -131,6 +131,31 @@ static int parse_args(int argc, char * argv[], int * out) {
return 0;
}
static void try_load_extensions(yutani_globals_t * yg) {
if (renderer_init) {
/* Already have a renderer extension loaded */
return;
}
/* Try to load cairo */
void * cairo = dlopen("libtoaru_ext_cairo_renderer.so", 0);
if (cairo) {
renderer_alloc = dlsym(cairo, "renderer_alloc");
renderer_init = dlsym(cairo, "renderer_init");
renderer_add_clip = dlsym(cairo, "renderer_add_clip");
renderer_set_clip = dlsym(cairo, "renderer_set_clip");
renderer_push_state = dlsym(cairo, "renderer_push_state");
renderer_pop_state = dlsym(cairo, "renderer_pop_state");
renderer_destroy = dlsym(cairo, "renderer_destroy");
renderer_blit_window = dlsym(cairo, "renderer_blit_window");
renderer_blit_screen = dlsym(cairo, "renderer_blit_screen");
}
/* On success, these are now set */
if (renderer_alloc) renderer_alloc(yg);
if (renderer_init) renderer_init(yg);
}
static int32_t min(int32_t a, int32_t b) {
return (a < b) ? a : b;
}
@ -1047,6 +1072,13 @@ static void redraw_windows(yutani_globals_t * yg) {
yutani_screenshot(yg);
}
if (yg->reload_renderer) {
yg->reload_renderer = 0;
/* Otherwise we won't draw the cursor... */
gfx_no_clip(yg->backend_ctx);
try_load_extensions(yg);
}
}
/**
@ -2086,21 +2118,7 @@ int main(int argc, char * argv[]) {
TRACE("Done.");
/* Try to load Cairo backend */
void * cairo = dlopen("libtoaru_ext_cairo_renderer.so", 0);
if (cairo) {
renderer_alloc = dlsym(cairo, "renderer_alloc");
renderer_init = dlsym(cairo, "renderer_init");
renderer_add_clip = dlsym(cairo, "renderer_add_clip");
renderer_set_clip = dlsym(cairo, "renderer_set_clip");
renderer_push_state = dlsym(cairo, "renderer_push_state");
renderer_pop_state = dlsym(cairo, "renderer_pop_state");
renderer_destroy = dlsym(cairo, "renderer_destroy");
renderer_blit_window = dlsym(cairo, "renderer_blit_window");
renderer_blit_screen = dlsym(cairo, "renderer_blit_screen");
}
if (renderer_alloc) renderer_alloc(yg);
if (renderer_init) renderer_init(yg);
try_load_extensions(yg);
yutani_clip_init(yg);
@ -2601,6 +2619,11 @@ int main(int argc, char * argv[]) {
pex_send(server, p->source, response->size, (char *)response);
}
break;
case YUTANI_SPECIAL_REQUEST_RELOAD:
{
yg->reload_renderer = 1;
}
break;
default:
TRACE("Unknown special request type: 0x%x", sr->request);
break;

View File

@ -25,6 +25,7 @@ void show_usage(int argc, char * argv[]) {
"usage: %s [-r?]\n"
"\n"
" -r \033[3mprint display resoluton\033[0m\n"
" -e \033[3mask compositor to reload extensions\033[0m\n"
" -? \033[3mshow this help text\033[0m\n"
"\n", argv[0]);
}
@ -41,10 +42,13 @@ int main(int argc, char * argv[]) {
return 1;
}
int opt;
while ((opt = getopt(argc, argv, "?r")) != -1) {
while ((opt = getopt(argc, argv, "?re")) != -1) {
switch (opt) {
case 'r':
return show_resolution();
case 'e':
yutani_special_request(yctx, NULL, YUTANI_SPECIAL_REQUEST_RELOAD);
return 0;
case '?':
show_usage(argc,argv);
return 0;

View File

@ -89,6 +89,7 @@ extern uint32_t premultiply(uint32_t color);
extern void gfx_add_clip(gfx_context_t * ctx, int32_t x, int32_t y, int32_t w, int32_t h);
extern void gfx_clear_clip(gfx_context_t * ctx);
extern void gfx_no_clip(gfx_context_t * ctx);
extern uint32_t getBilinearFilteredPixelColor(sprite_t * tex, double u, double v);

View File

@ -282,6 +282,8 @@ typedef struct YutaniGlobals {
/* Renderer plugin context */
void * renderer_ctx;
int reload_renderer;
} yutani_globals_t;
struct key_bind {

View File

@ -443,6 +443,8 @@ struct yutani_msg_clipboard {
#define YUTANI_SPECIAL_REQUEST_CLIPBOARD 10
#define YUTANI_SPECIAL_REQUEST_RELOAD 20
/*
* YUTANI_RESIZE
*

View File

@ -64,6 +64,13 @@ void gfx_clear_clip(gfx_context_t * ctx) {
}
}
void gfx_no_clip(gfx_context_t * ctx) {
void * tmp = ctx->clips;
if (!tmp) return;
ctx->clips = NULL;
free(tmp);
}
/* Pointer to graphics memory */
void flip(gfx_context_t * ctx) {
if (ctx->clips) {