diff --git a/src/backend/x11/backend.c b/src/backend/x11/backend.c index b1713c5..1e385a7 100644 --- a/src/backend/x11/backend.c +++ b/src/backend/x11/backend.c @@ -337,3 +337,9 @@ void backend_detect_destroy(backend_detect_t *detect) { p_delete(&detect->outputs); free(detect); } + +bool backend_apply_effect(backend_t *backend, const effect_t *effects, + size_t effect_count) { + /* TODO: */ + return true; +} diff --git a/src/core/backend.h b/src/core/backend.h index cfdec89..b3722ec 100644 --- a/src/core/backend.h +++ b/src/core/backend.h @@ -3,6 +3,7 @@ #include #include "core/event.h" +#include "core/plan.h" #include "core/types.h" typedef struct backend_t backend_t; @@ -31,3 +32,5 @@ void backend_detect_destroy(backend_detect_t *detect); * 无需 cleanup 的状态,调用方可以直接退出循环。 */ bool backend_next_event(backend_t *backend, event_t *event); +bool backend_apply_effect(backend_t *backend, const effect_t *effects, + size_t effect_count); diff --git a/src/core/plan.c b/src/core/plan.c new file mode 100644 index 0000000..d3a3c05 --- /dev/null +++ b/src/core/plan.c @@ -0,0 +1,22 @@ +#include "core/plan.h" + +#include "base/array.h" +#include "base/memory.h" + +void plan_reset(plan_t *plan) { + if (!plan->effects || !plan->capacity) return; + + p_clear(plan->effects, plan->capacity); + plan->count = 0; +} + +void plan_cleanup(plan_t *plan) { + p_delete(&plan->effects); + plan->count = 0; + plan->capacity = 0; +} + +void plan_push_effect(plan_t *plan, const effect_t *effect) { + effect_t *eft = array_push(plan->effects, plan->count, plan->capacity); + *eft = *effect; +} diff --git a/src/core/plan.h b/src/core/plan.h new file mode 100644 index 0000000..d74a849 --- /dev/null +++ b/src/core/plan.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +#include "core/types.h" + +typedef uint32_t dirty_mask_t; + +typedef enum dirty_flags_t : dirty_mask_t { + ZDWM_DIRTY_NONE = 0, + ZDWM_DIRTY_LAYOUT = 1u << 0, +} dirty_flags_t; + +typedef enum effect_type_t { + ZDWM_EFFECT_NONE, + ZDWM_EFFECT_MAP_WINDOW, + ZDWM_EFFECT_UNMAP_WINDOW, + ZDWM_EFFECT_FOCUS_WINDOW, +} effect_type_t; + +typedef struct effect_only_window_id_t { + window_id_t window; +} effect_only_window_id_t; + +typedef struct effect_t { + effect_type_t type; + union { + effect_only_window_id_t map; + effect_only_window_id_t unmap; + effect_only_window_id_t focus; + } as; +} effect_t; + +typedef struct plan_t { + effect_t *effects; + size_t count; + size_t capacity; + dirty_mask_t dirty_flags; +} plan_t; + +void plan_reset(plan_t *plan); +void plan_cleanup(plan_t *plan); +void plan_push_effect(plan_t *plan, const effect_t *effect); diff --git a/src/core/policy.c b/src/core/policy.c index 5c43169..dcb6a1a 100644 --- a/src/core/policy.c +++ b/src/core/policy.c @@ -102,3 +102,10 @@ bool policy_route_event(const policy_context_t *ctx, command_buffer_t *out) { return false; } } + +bool policy_apply_command(const policy_context_t *ctx, + const command_buffer_t *command_buffer, + plan_t *plan) { + /* TODO: */ + return true; +} diff --git a/src/core/policy.h b/src/core/policy.h index 14f0f0d..c0b558f 100644 --- a/src/core/policy.h +++ b/src/core/policy.h @@ -2,6 +2,7 @@ #include "core/command_buffer.h" #include "core/event.h" +#include "core/plan.h" #include "core/rules.h" #include "core/state.h" @@ -12,3 +13,5 @@ typedef struct policy_context_t { } policy_context_t; bool policy_route_event(const policy_context_t *ctx, command_buffer_t *out); +bool policy_apply_command(const policy_context_t *ctx, + const command_buffer_t *command_buffer, plan_t *plan); diff --git a/src/core/runtime.c b/src/core/runtime.c index 51f6ef9..497d5ff 100644 --- a/src/core/runtime.c +++ b/src/core/runtime.c @@ -4,8 +4,11 @@ #include "base/memory.h" #include "core/backend.h" +#include "core/command_buffer.h" #include "core/event.h" #include "core/layout.h" +#include "core/plan.h" +#include "core/policy.h" #include "core/rules.h" #include "core/state.h" #include "core/wm_desc.h" @@ -82,6 +85,8 @@ void runtime_init_desc_cleanup(runtime_init_desc_t *desc) { void runtime_shutdown(runtime_t *runtime) { runtime->running = false; + plan_cleanup(&runtime->plan); + command_buffer_cleanup(&runtime->command_buffer); layout_registry_cleanup(&runtime->layouts); rules_cleanup(&runtime->rules); state_cleanup(&runtime->state); @@ -92,11 +97,28 @@ void runtime_shutdown(runtime_t *runtime) { } void runtime_run(runtime_t *runtime) { - for (;;) { + runtime->running = true; + + backend_t *backend = runtime->backend; + command_buffer_t *command_buffer = &runtime->command_buffer; + plan_t *plan = &runtime->plan; + + while (runtime->running) { event_t event = {0}; - if (!backend_next_event(runtime->backend, &event)) { - break; - } + if (!backend_next_event(backend, &event)) break; + + command_buffer_reset(command_buffer); + plan_reset(plan); + + policy_context_t ctx = { + .state = &runtime->state, + .rules = &runtime->rules, + .event = &event, + }; + + policy_route_event(&ctx, command_buffer); + policy_apply_command(&ctx, command_buffer, plan); + if (plan->count) backend_apply_effect(backend, plan->effects, plan->count); event_cleanup(&event); } diff --git a/src/core/runtime.h b/src/core/runtime.h index d46ae2a..b3cb140 100644 --- a/src/core/runtime.h +++ b/src/core/runtime.h @@ -5,6 +5,7 @@ #include "core/backend.h" #include "core/command_buffer.h" #include "core/layout.h" +#include "core/plan.h" #include "core/rules.h" #include "core/state.h" @@ -24,6 +25,7 @@ typedef struct runtime_t { bool running; bool will_restart; + plan_t plan; command_buffer_t command_buffer; state_t state; layout_registry_t layouts; diff --git a/tests/config/CMakeLists.txt b/tests/config/CMakeLists.txt index f58afde..22059c7 100644 --- a/tests/config/CMakeLists.txt +++ b/tests/config/CMakeLists.txt @@ -41,9 +41,12 @@ add_executable(${RUNTIME_CONFIG_TEST_APP_NAME} ${SOURCE_DIR}/config/defaults.c ${SOURCE_DIR}/config/loader.c ${SOURCE_DIR}/config/runtime_config.c + ${SOURCE_DIR}/core/command_buffer.c ${SOURCE_DIR}/core/event.c ${SOURCE_DIR}/core/layer.c ${SOURCE_DIR}/core/layout.c + ${SOURCE_DIR}/core/plan.c + ${SOURCE_DIR}/core/policy.c ${SOURCE_DIR}/core/rules.c ${SOURCE_DIR}/core/runtime.c ${SOURCE_DIR}/core/state.c diff --git a/tests/config/runtime_config_test.c b/tests/config/runtime_config_test.c index bfc847d..449edc2 100644 --- a/tests/config/runtime_config_test.c +++ b/tests/config/runtime_config_test.c @@ -22,6 +22,11 @@ bool backend_next_event(backend_t *backend, event_t *event) { return false; } +bool backend_apply_effect(backend_t *backend, const effect_t *effects, + size_t effect_count) { + return false; +} + static backend_t *test_backend_create(void) { return calloc(1, sizeof(backend_t)); } diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt index bcc4cd6..6d952f6 100644 --- a/tests/core/CMakeLists.txt +++ b/tests/core/CMakeLists.txt @@ -10,9 +10,12 @@ add_executable(${TEST_APP_NAME} ${SOURCE_DIR}/backend/x11/backend.c ${SOURCE_DIR}/backend/x11/event.c ${SOURCE_DIR}/backend/x11/window.c + ${SOURCE_DIR}/core/command_buffer.c ${SOURCE_DIR}/core/event.c ${SOURCE_DIR}/core/layer.c ${SOURCE_DIR}/core/layout.c + ${SOURCE_DIR}/core/plan.c + ${SOURCE_DIR}/core/policy.c ${SOURCE_DIR}/core/rules.c ${SOURCE_DIR}/core/runtime.c ${SOURCE_DIR}/core/state.c