mirror of
				https://github.com/yshui/picom.git
				synced 2025-10-30 23:46:46 -04:00 
			
		
		
		
	api: introduce the concept of backend specific plugins
Allow loaded plugins to hook into specific backends. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
		
							parent
							
								
									21fe5983e0
								
							
						
					
					
						commit
						bbde4bb1ab
					
				
					 4 changed files with 91 additions and 4 deletions
				
			
		| 
						 | 
				
			
			@ -3,12 +3,31 @@
 | 
			
		|||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#define PICOM_API_MAJOR (0UL)
 | 
			
		||||
#define PICOM_API_MINOR (1UL)
 | 
			
		||||
 | 
			
		||||
struct picom_api {};
 | 
			
		||||
struct backend_base;
 | 
			
		||||
 | 
			
		||||
/// The entry point of a backend plugin. Called after the backend is initialized.
 | 
			
		||||
typedef void (*picom_backend_plugin_entrypoint)(struct backend_base *backend, void *user_data);
 | 
			
		||||
struct picom_api {
 | 
			
		||||
	/// Add a plugin for a specific backend. The plugin's entry point will be called
 | 
			
		||||
	/// when the specified backend is initialized.
 | 
			
		||||
	///
 | 
			
		||||
	/// @param backend_name The name of the backend to add the plugin to.
 | 
			
		||||
	/// @param major        The major version of the backend API interface this plugin
 | 
			
		||||
	///                     is compatible with.
 | 
			
		||||
	/// @param minor        The minor version of the backend API interface this plugin
 | 
			
		||||
	///                     is compatible with.
 | 
			
		||||
	/// @param entrypoint   The entry point of the plugin.
 | 
			
		||||
	/// @param user_data    The user data to pass to the plugin's entry point.
 | 
			
		||||
	bool (*add_backend_plugin)(const char *backend_name, uint64_t major, uint64_t minor,
 | 
			
		||||
	                           picom_backend_plugin_entrypoint entrypoint,
 | 
			
		||||
	                           void *user_data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const struct picom_api *
 | 
			
		||||
picom_api_get_interfaces(uint64_t major, uint64_t minor, const char *context);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										65
									
								
								src/api.c
									
										
									
									
									
								
							
							
						
						
									
										65
									
								
								src/api.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -6,10 +6,69 @@
 | 
			
		|||
#include <picom/api.h>
 | 
			
		||||
#include <picom/backend.h>
 | 
			
		||||
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include <uthash.h>
 | 
			
		||||
 | 
			
		||||
static struct picom_api picom_api;
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "utils.h"
 | 
			
		||||
 | 
			
		||||
struct backend_plugins {
 | 
			
		||||
	UT_hash_handle hh;
 | 
			
		||||
	const char *backend_name;
 | 
			
		||||
	struct list_node plugins;
 | 
			
		||||
} *backend_plugins;
 | 
			
		||||
 | 
			
		||||
struct backend_plugin {
 | 
			
		||||
	const char *backend_name;
 | 
			
		||||
	picom_backend_plugin_entrypoint entrypoint;
 | 
			
		||||
	void *user_data;
 | 
			
		||||
	struct list_node siblings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool add_backend_plugin(const char *backend_name, uint64_t major, uint64_t minor,
 | 
			
		||||
                               picom_backend_plugin_entrypoint entrypoint, void *user_data) {
 | 
			
		||||
	if (major != PICOM_BACKEND_MAJOR || minor > PICOM_BACKEND_MINOR) {
 | 
			
		||||
		log_error("Cannot add plugin for backend %s, because the requested "
 | 
			
		||||
		          "version %" PRIu64 ".%" PRIu64 " is incompatible with the our "
 | 
			
		||||
		          "%lu.%lu",
 | 
			
		||||
		          backend_name, major, minor, PICOM_BACKEND_MAJOR,
 | 
			
		||||
		          PICOM_BACKEND_MINOR);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto plugin = ccalloc(1, struct backend_plugin);
 | 
			
		||||
	plugin->backend_name = backend_name;
 | 
			
		||||
	plugin->entrypoint = entrypoint;
 | 
			
		||||
	plugin->user_data = user_data;
 | 
			
		||||
 | 
			
		||||
	struct backend_plugins *plugins = NULL;
 | 
			
		||||
	HASH_FIND_STR(backend_plugins, backend_name, plugins);
 | 
			
		||||
	if (!plugins) {
 | 
			
		||||
		plugins = ccalloc(1, struct backend_plugins);
 | 
			
		||||
		plugins->backend_name = strdup(backend_name);
 | 
			
		||||
		list_init_head(&plugins->plugins);
 | 
			
		||||
		HASH_ADD_STR(backend_plugins, backend_name, plugins);
 | 
			
		||||
	}
 | 
			
		||||
	list_insert_after(&plugins->plugins, &plugin->siblings);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void api_backend_plugins_invoke(const char *backend_name, struct backend_base *backend) {
 | 
			
		||||
	struct backend_plugins *plugins = NULL;
 | 
			
		||||
	HASH_FIND_STR(backend_plugins, backend_name, plugins);
 | 
			
		||||
	if (!plugins) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_foreach(struct backend_plugin, plugin, &plugins->plugins, siblings) {
 | 
			
		||||
		plugin->entrypoint(backend, plugin->user_data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct picom_api picom_api = {
 | 
			
		||||
    .add_backend_plugin = add_backend_plugin,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
PICOM_PUBLIC_API const struct picom_api *
 | 
			
		||||
picom_api_get_interfaces(uint64_t major, uint64_t minor, const char *context) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								src/api_internal.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/api_internal.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
// SPDX-License-Identifier: MPL-2.0
 | 
			
		||||
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
 | 
			
		||||
 | 
			
		||||
struct backend_base;
 | 
			
		||||
 | 
			
		||||
/// Invoke all backend plugins for the specified backend.
 | 
			
		||||
void api_backend_plugins_invoke(const char *backend_name, struct backend_base *backend);
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +41,7 @@
 | 
			
		|||
#include <picom/types.h>
 | 
			
		||||
#include <test.h>
 | 
			
		||||
 | 
			
		||||
#include "api_internal.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "compiler.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -660,6 +661,7 @@ static bool initialize_backend(session_t *ps) {
 | 
			
		|||
		// Reinitialize win_data
 | 
			
		||||
		ps->backend_data =
 | 
			
		||||
		    backend_init(ps->o.backend, ps, session_get_target_window(ps));
 | 
			
		||||
		api_backend_plugins_invoke(backend_name(ps->o.backend), ps->backend_data);
 | 
			
		||||
		if (!ps->backend_data) {
 | 
			
		||||
			log_fatal("Failed to initialize backend, aborting...");
 | 
			
		||||
			quit(ps);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue