Browse Source

Allow compositor to load Cairo backend later at runtime

K. Lange 2 years ago
parent
commit
719d27166d

+ 38 - 15
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;

+ 5 - 1
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;

+ 1 - 0
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);
 

+ 2 - 0
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 {

+ 2 - 0
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
  *

+ 7 - 0
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) {