1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-04-07 17:44:04 -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:
Yuxuan Shui 2024-05-23 16:00:10 +01:00
parent 21fe5983e0
commit bbde4bb1ab
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
4 changed files with 91 additions and 4 deletions

View file

@ -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);

View file

@ -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
View 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);

View file

@ -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);