diff --git a/apps/compositor.c b/apps/compositor.c index f29a1ef2..9f7ebea1 100644 --- a/apps/compositor.c +++ b/apps/compositor.c @@ -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; diff --git a/apps/yutani-query.c b/apps/yutani-query.c index a528fc1a..079dece2 100644 --- a/apps/yutani-query.c +++ b/apps/yutani-query.c @@ -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; diff --git a/base/usr/include/toaru/graphics.h b/base/usr/include/toaru/graphics.h index ea7b53e6..25f99aa7 100644 --- a/base/usr/include/toaru/graphics.h +++ b/base/usr/include/toaru/graphics.h @@ -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); diff --git a/base/usr/include/toaru/yutani-server.h b/base/usr/include/toaru/yutani-server.h index 05beec9b..d0884d85 100644 --- a/base/usr/include/toaru/yutani-server.h +++ b/base/usr/include/toaru/yutani-server.h @@ -282,6 +282,8 @@ typedef struct YutaniGlobals { /* Renderer plugin context */ void * renderer_ctx; + + int reload_renderer; } yutani_globals_t; struct key_bind { diff --git a/base/usr/include/toaru/yutani.h b/base/usr/include/toaru/yutani.h index 0e550ae2..bcbc723a 100644 --- a/base/usr/include/toaru/yutani.h +++ b/base/usr/include/toaru/yutani.h @@ -443,6 +443,8 @@ struct yutani_msg_clipboard { #define YUTANI_SPECIAL_REQUEST_CLIPBOARD 10 +#define YUTANI_SPECIAL_REQUEST_RELOAD 20 + /* * YUTANI_RESIZE * diff --git a/lib/graphics.c b/lib/graphics.c index 737355f6..8e21beb4 100644 --- a/lib/graphics.c +++ b/lib/graphics.c @@ -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) {