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:
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
Reference in a new issue