事件适配器

This commit is contained in:
2025-08-19 00:42:42 +08:00
parent 4252604c52
commit 36941aef25
7 changed files with 219 additions and 15 deletions

105
src/include/event-adapter.h Normal file
View File

@@ -0,0 +1,105 @@
#pragma once
#include <stdint.h>
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);

View File

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

View File

@@ -11,6 +11,7 @@
#include <wordexp.h>
#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();
}

View File

@@ -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}"
)

100
src/xcb/event.c Normal file
View File

@@ -0,0 +1,100 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xcb_event.h>
#include <xcb/xproto.h>
#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;
}
}

View File

@@ -1,9 +1,12 @@
#pragma once
#include <xcb/xcb_keysyms.h>
#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);

View File

@@ -2,7 +2,6 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xcb/xcb.h>
@@ -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();