From 36941aef2500f79a5fda3692f400f66aa7e2984d Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Tue, 19 Aug 2025 00:42:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E9=80=82=E9=85=8D=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/event-adapter.h | 105 ++++++++++++++++++++++++++++++++++++ src/include/xcb.h | 1 - src/main.c | 10 +++- src/xcb/CMakeLists.txt | 3 +- src/xcb/event.c | 100 ++++++++++++++++++++++++++++++++++ src/xcb/xcb-private.h | 3 ++ src/xcb/xcb.c | 12 +---- 7 files changed, 219 insertions(+), 15 deletions(-) create mode 100644 src/include/event-adapter.h create mode 100644 src/xcb/event.c diff --git a/src/include/event-adapter.h b/src/include/event-adapter.h new file mode 100644 index 0000000..497f98c --- /dev/null +++ b/src/include/event-adapter.h @@ -0,0 +1,105 @@ +#pragma once + +#include + +typedef enum event_type_t { + EVENT_TYPE_MAPPING_NOTIFY, + EVENT_TYPE_KEY_PRESS, + EVENT_TYPE_BUTTON_PRESS, + EVENT_TYPE_CONFIGURE_REQUEST, + EVENT_TYPE_CONFIGURE_NOTIFY, + EVENT_TYPE_MAP_REQUEST, + EVENT_TYPE_UNMAP_NOTIFY, + EVENT_TYPE_DESTROY_NOTIFY, + EVENT_TYPE_EXPOSE, + EVENT_TYPE_MOTION_NOTIFY, + EVENT_TYPE_ENTER_NOTIFY, + EVENT_TYPE_FOCUS_IN, + EVENT_TYPE_PROPERTY_NOTIFY, + EVENT_TYPE_CLIENT_MESSAGE, +} event_type_t; + +typedef struct mapping_notify_event_t { + event_type_t type; +} mapping_notify_event_t; + +typedef struct key_press_event_t { + event_type_t type; + uint32_t key_symbols; + uint32_t modifiers; +} key_press_event_t; + +typedef struct button_press_event_t { + event_type_t type; +} button_press_event_t; + +typedef struct configure_request_event_t { + event_type_t type; +} configure_request_event_t; + +typedef struct configure_notify_event_t { + event_type_t type; +} configure_notify_event_t; + +typedef struct map_request_event_t { + event_type_t type; +} map_request_event_t; + +typedef struct unmap_notify_event_t { + event_type_t type; +} unmap_notify_event_t; + +typedef struct destroy_notify_event_t { + event_type_t type; +} destroy_notify_event_t; + +typedef struct expose_event_t { + event_type_t type; +} expose_event_t; + +typedef struct motion_notify_event_t { + event_type_t type; +} motion_notify_event_t; + +typedef struct enter_notify_event_t { + event_type_t type; +} enter_notify_event_t; + +typedef struct focus_in_event_t { + event_type_t type; +} focus_in_event_t; + +typedef struct property_notify_event_t { + event_type_t type; +} property_notify_event_t; + +typedef struct client_message_event_t { + event_type_t type; +} client_message_event_t; + +typedef union generic_event_t { + event_type_t type; + mapping_notify_event_t mapping_notify; + key_press_event_t key_press; + button_press_event_t button_press; + configure_request_event_t configure_request; + configure_notify_event_t configure_notify; + map_request_event_t map_request; + unmap_notify_event_t unmap_notify; + destroy_notify_event_t destroy_notify; + expose_event_t expose; + motion_notify_event_t motiion_notify; + enter_notify_event_t enter_notify; + focus_in_event_t focus_in; + property_notify_event_t property_notify; + client_message_event_t client_message; +} generic_event_t; + +typedef void (*event_handler)(generic_event_t *event, void *user_data); + +typedef struct event_adapter_t event_adapter_t; +event_adapter_t *create_event_adapter(void); +void destroy_event_adapter(event_adapter_t *adapter); +void event_adapter_set_handler(event_adapter_t *adapter, event_handler handler, + void *user_data); +void event_adapter_poll(event_adapter_t *adapter); diff --git a/src/include/xcb.h b/src/include/xcb.h index 2e65c96..ae8ff80 100644 --- a/src/include/xcb.h +++ b/src/include/xcb.h @@ -54,7 +54,6 @@ typedef struct window_list_t { } window_list_t; window_list_t *scan_window_list(void); void free_window_list(window_list_t *window_list); -void start_xcb_event_loop(void); void clean_xcb(void); bool get_xresource_uint32(const char *name, uint32_t *value); diff --git a/src/main.c b/src/main.c index ea9bd32..ef64bc2 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include #include "config.h" +#include "event-adapter.h" #include "renderer.h" #include "types.h" #include "utils.h" @@ -38,6 +39,7 @@ static monitor_t *current_monitor = NULL; static wallpaper_config_t *wallpaper_config = NULL; static color_set_t *color_set = NULL; static GMainLoop *loop = NULL; +static event_adapter_t *adapter = NULL; static char *font_family = NULL; static uint32_t font_size = default_font_size; static uint32_t dpi = dpi_fallback; @@ -353,6 +355,7 @@ void update_bars(void) { } void init_xcb_event_loop(void) { + adapter = create_event_adapter(); GIOChannel *channel = g_io_channel_unix_new(get_xcb_connection_fd()); g_io_channel_set_encoding(channel, NULL, NULL); GIOCondition cond = G_IO_IN | G_IO_HUP | G_IO_ERR; @@ -362,12 +365,12 @@ void init_xcb_event_loop(void) { gboolean handle_xcb_event(GIOChannel *channel, GIOCondition condition, gpointer userdata) { - if ((condition & G_IO_HUP) || (condition & G_IO_ERR)) { + if (condition & (G_IO_HUP | G_IO_ERR)) { g_main_loop_quit(loop); return false; } - start_xcb_event_loop(); + event_adapter_poll(adapter); return true; } @@ -400,6 +403,9 @@ void cleanup(void) { } monitors = NULL; + destroy_event_adapter(adapter); + adapter = NULL; + clean_xcb(); } diff --git a/src/xcb/CMakeLists.txt b/src/xcb/CMakeLists.txt index 5365586..6ad5466 100644 --- a/src/xcb/CMakeLists.txt +++ b/src/xcb/CMakeLists.txt @@ -1,12 +1,13 @@ set(LIB_XCB "zswm-xcb") set(LIB_XCB_NAME ${LIB_XCB} PARENT_SCOPE) -add_library(${LIB_XCB} STATIC xcb.c window.c res.c cursor.c) +add_library(${LIB_XCB} STATIC xcb.c window.c res.c cursor.c event.c) target_include_directories(${LIB_XCB} SYSTEM PRIVATE ${XCB_INCLUDE_DIRS} ) target_include_directories(${LIB_XCB} + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" PRIVATE "${CMAKE_SOURCE_DIR}/include" PRIVATE "${CMAKE_BINARY_DIR}" ) diff --git a/src/xcb/event.c b/src/xcb/event.c new file mode 100644 index 0000000..35309b4 --- /dev/null +++ b/src/xcb/event.c @@ -0,0 +1,100 @@ +#include +#include +#include +#include +#include +#include + +#include "event-adapter.h" +#include "utils.h" +#include "xcb-private.h" + +struct event_adapter_t { + xcb_connection_t *conn; + event_handler handler; + void *user_data; +}; + +static void convert_event(xcb_generic_event_t *xcb_event, + generic_event_t *event) { + uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(xcb_event); + const char *label = xcb_event_get_label(event_type); + printf("=========================== %s ===========================\n", label); + switch (event_type) { + case XCB_MAPPING_NOTIFY: + event->type = EVENT_TYPE_MAPPING_NOTIFY; + break; + case XCB_KEY_PRESS: { + xcb_key_press_event_t *ev = (xcb_key_press_event_t *)xcb_event; + int col = ev->state & XCB_MOD_MASK_2 ? 1 : 0; + xcb_keysym_t keysym = xcb_key_press_lookup_keysym(key_symbols, ev, col); + event->key_press.type = EVENT_TYPE_KEY_PRESS; + event->key_press.key_symbols = keysym; + event->key_press.modifiers = ev->state; + break; + } + case XCB_BUTTON_PRESS: + event->type = EVENT_TYPE_BUTTON_PRESS; + break; + case XCB_CONFIGURE_REQUEST: + event->type = EVENT_TYPE_CONFIGURE_REQUEST; + break; + case XCB_CONFIGURE_NOTIFY: + event->type = EVENT_TYPE_CONFIGURE_NOTIFY; + break; + case XCB_MAP_REQUEST: + event->type = EVENT_TYPE_MAP_REQUEST; + break; + case XCB_UNMAP_NOTIFY: + event->type = EVENT_TYPE_UNMAP_NOTIFY; + break; + case XCB_DESTROY_NOTIFY: + event->type = EVENT_TYPE_DESTROY_NOTIFY; + break; + case XCB_EXPOSE: + event->type = EVENT_TYPE_EXPOSE; + break; + case XCB_MOTION_NOTIFY: + event->type = EVENT_TYPE_MOTION_NOTIFY; + break; + case XCB_ENTER_NOTIFY: + event->type = EVENT_TYPE_ENTER_NOTIFY; + break; + case XCB_FOCUS_IN: + event->type = EVENT_TYPE_FOCUS_IN; + break; + case XCB_PROPERTY_NOTIFY: + event->type = EVENT_TYPE_PROPERTY_NOTIFY; + break; + case XCB_CLIENT_MESSAGE: + event->type = EVENT_TYPE_CLIENT_MESSAGE; + break; + default: + return; + } +} + +event_adapter_t *create_event_adapter(void) { + event_adapter_t *adapter = ecalloc(1, sizeof(event_adapter_t)); + adapter->conn = conn; + return adapter; +} + +void destroy_event_adapter(event_adapter_t *adapter) { free(adapter); } + +void event_adapter_set_handler(event_adapter_t *adapter, event_handler handler, + void *user_data) { + adapter->handler = handler; + adapter->user_data = user_data; +} + +void event_adapter_poll(event_adapter_t *adapter) { + xcb_generic_event_t *xcb_event; + generic_event_t event; + while ((xcb_event = xcb_poll_for_event(adapter->conn))) { + convert_event(xcb_event, &event); + if (adapter->handler) adapter->handler(&event, adapter->user_data); + free(xcb_event); + xcb_event = NULL; + } +} diff --git a/src/xcb/xcb-private.h b/src/xcb/xcb-private.h index 123c9b2..0b54ff5 100644 --- a/src/xcb/xcb-private.h +++ b/src/xcb/xcb-private.h @@ -1,9 +1,12 @@ #pragma once +#include + #include "xcb.h" extern xcb_connection_t *conn; extern xcb_screen_t *screen; +extern xcb_key_symbols_t *key_symbols; xcb_cursor_t get_xcb_cursor(cursor_t cursor); void clean_xcb_cursor(void); diff --git a/src/xcb/xcb.c b/src/xcb/xcb.c index 16bbf4e..0045fbc 100644 --- a/src/xcb/xcb.c +++ b/src/xcb/xcb.c @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -21,6 +20,7 @@ xcb_connection_t *conn = NULL; xcb_screen_t *screen = NULL; +xcb_key_symbols_t *key_symbols = NULL; bool has_other_wm_running(void) { conn = xcb_connect(NULL, NULL); @@ -276,16 +276,6 @@ void free_window_list(window_list_t *window_list) { free(window_list); } -void start_xcb_event_loop(void) { - xcb_generic_event_t *event = NULL; - while ((event = xcb_poll_for_event(conn)) != NULL) { - uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(event); - const char *label = xcb_event_get_label(event_type); - printf("================== %s ==================\n", label); - free(event); - } -} - void clean_xcb(void) { clean_xcb_cursor();