1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-04-14 17:53:25 -04:00

core: move information about the x extensions into a separate structure

This commit is contained in:
Maxim Solovyov 2024-10-18 20:56:26 +03:00
parent 61e1b178e5
commit 97ec926a9f
No known key found for this signature in database
9 changed files with 77 additions and 83 deletions

View file

@ -233,7 +233,7 @@ static backend_t *glx_init(session_t *ps, xcb_window_t target) {
XVisualInfo *pvis = NULL;
// Check for GLX extension
if (!ps->glx_exists) {
if (!ps->c.e.has_glx) {
log_error("No GLX extension.");
goto end;
}

View file

@ -892,7 +892,7 @@ static backend_t *xrender_init(session_t *ps, xcb_window_t target) {
XCB_RENDER_CP_SUBWINDOW_MODE, &pa);
xd->vsync = ps->o.vsync;
if (ps->present_exists) {
if (ps->c.e.has_present) {
auto eid = x_new_id(&ps->c);
auto e =
xcb_request_check(ps->c.c, xcb_present_select_input_checked(

View file

@ -207,36 +207,8 @@ typedef struct session {
long paint_tm_offset;
// === X extension related ===
/// Error base number for X Fixes extension.
int xfixes_error;
/// Event base number for X Damage extension.
int damage_event;
/// Error base number for X Damage extension.
int damage_error;
/// Error base number for X Render extension.
int render_error;
/// Whether X Shape extension exists.
bool shape_exists;
/// Event base number for X Shape extension.
int shape_event;
/// Whether X RandR extension exists.
bool randr_exists;
/// Event base number for X RandR extension.
int randr_event;
/// Whether X Present extension exists.
bool present_exists;
/// Whether X GLX extension exists.
bool glx_exists;
/// Error base number for X GLX extension.
int glx_error;
/// Information about monitors.
struct x_monitors monitors;
/// Whether X Sync extension exists.
bool xsync_exists;
/// Event base number for X Sync extension.
int xsync_event;
/// Error base number for X Sync extension.
int xsync_error;
// === Atoms ===
struct atom *atoms;

View file

@ -16,9 +16,9 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r
printf("**Version:** " PICOM_FULL_VERSION "\n");
// printf("**CFLAGS:** %s\n", "??");
printf("\n### Extensions:\n\n");
printf("* Shape: %s\n", ps->shape_exists ? "Yes" : "No");
printf("* RandR: %s\n", ps->randr_exists ? "Yes" : "No");
printf("* Present: %s\n", ps->present_exists ? "Present" : "Not Present");
printf("* Shape: %s\n", ps->c.e.has_shape ? "Yes" : "No");
printf("* RandR: %s\n", ps->c.e.has_randr ? "Yes" : "No");
printf("* Present: %s\n", ps->c.e.has_present ? "Present" : "Not Present");
printf("\n### Misc:\n\n");
printf("* Use Overlay: %s\n", ps->overlay != XCB_NONE ? "Yes" : "No");
if (ps->overlay == XCB_NONE) {

View file

@ -101,11 +101,11 @@ static inline xcb_window_t attr_pure ev_window(session_t *ps, xcb_generic_event_
case XCB_PROPERTY_NOTIFY: return ((xcb_property_notify_event_t *)ev)->window;
case XCB_CLIENT_MESSAGE: return ((xcb_client_message_event_t *)ev)->window;
default:
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
if (ps->c.e.damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
return ((xcb_damage_notify_event_t *)ev)->drawable;
}
if (ps->shape_exists && ev->response_type == ps->shape_event) {
if (ps->c.e.has_shape && ev->response_type == ps->c.e.shape_event) {
return ((xcb_shape_notify_event_t *)ev)->affected_window;
}
@ -133,16 +133,16 @@ static inline const char *ev_name(session_t *ps, xcb_generic_event_t *ev) {
CASESTRRET(CLIENT_MESSAGE);
}
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
if (ps->c.e.damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
return "DAMAGE_NOTIFY";
}
if (ps->shape_exists && ev->response_type == ps->shape_event) {
if (ps->c.e.has_shape && ev->response_type == ps->c.e.shape_event) {
return "SHAPE_NOTIFY";
}
if (ps->xsync_exists) {
int o = ev->response_type - ps->xsync_event;
if (ps->c.e.has_sync) {
int o = ev->response_type - ps->c.e.sync_event;
switch (o) {
CASESTRRET(SYNC_COUNTER_NOTIFY);
CASESTRRET(SYNC_ALARM_NOTIFY);
@ -717,7 +717,7 @@ ev_selection_clear(session_t *ps, xcb_selection_clear_event_t attr_unused *ev) {
void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
xcb_window_t wid = ev_window(ps, ev);
if (ev->response_type != ps->damage_event + XCB_DAMAGE_NOTIFY) {
if (ev->response_type != ps->c.e.damage_event + XCB_DAMAGE_NOTIFY) {
log_debug("event %10.10s serial %#010x window %#010x \"%s\"",
ev_name(ps, ev), ev->full_sequence, wid, ev_window_name(ps, wid));
} else {
@ -786,16 +786,17 @@ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
ev_selection_clear(ps, (xcb_selection_clear_event_t *)ev);
break;
default:
if (ps->shape_exists && ev->response_type == ps->shape_event) {
if (ps->c.e.has_shape && ev->response_type == ps->c.e.shape_event) {
ev_shape_notify(ps, (xcb_shape_notify_event_t *)ev);
break;
}
if (ps->randr_exists &&
ev->response_type == (ps->randr_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
if (ps->c.e.has_randr &&
ev->response_type ==
(ps->c.e.randr_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY)) {
x_update_monitors_async(&ps->c, &ps->monitors);
break;
}
if (ps->damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
if (ps->c.e.damage_event + XCB_DAMAGE_NOTIFY == ev->response_type) {
ev_damage_notify(ps, (xcb_damage_notify_event_t *)ev);
break;
}

View file

@ -1204,7 +1204,7 @@ static bool redirect_start(session_t *ps) {
ps->drivers = detect_driver(ps->c.c, ps->backend_data, ps->c.screen_info->root);
apply_driver_workarounds(ps, ps->drivers);
if (ps->present_exists && ps->frame_pacing) {
if (ps->c.e.has_present && ps->frame_pacing) {
// Initialize rendering and frame timing statistics, and frame pacing
// states.
ps->last_msc_instant = 0;
@ -1979,17 +1979,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
.last_msc = 0,
.xfixes_error = 0,
.damage_event = 0,
.damage_error = 0,
.render_error = 0,
.shape_exists = false,
.shape_event = 0,
.randr_exists = 0,
.randr_event = 0,
.glx_exists = false,
.glx_error = 0,
#ifdef CONFIG_DBUS
.dbus_data = NULL,
#endif
@ -2034,7 +2023,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
log_fatal("No render extension");
exit(1);
}
ps->render_error = ext_info->first_error;
ps->c.e.render_error = ext_info->first_error;
ext_info = xcb_get_extension_data(ps->c.c, &xcb_composite_id);
if (!ext_info || !ext_info->present) {
@ -2062,8 +2051,8 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
log_fatal("No damage extension");
exit(1);
}
ps->damage_event = ext_info->first_event;
ps->damage_error = ext_info->first_error;
ps->c.e.damage_event = ext_info->first_event;
ps->c.e.damage_error = ext_info->first_error;
xcb_discard_reply(ps->c.c, xcb_damage_query_version(ps->c.c, XCB_DAMAGE_MAJOR_VERSION,
XCB_DAMAGE_MINOR_VERSION)
.sequence);
@ -2073,7 +2062,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
log_fatal("No XFixes extension");
exit(1);
}
ps->xfixes_error = ext_info->first_error;
ps->c.e.fixes_error = ext_info->first_error;
xcb_discard_reply(ps->c.c, xcb_xfixes_query_version(ps->c.c, XCB_XFIXES_MAJOR_VERSION,
XCB_XFIXES_MINOR_VERSION)
.sequence);
@ -2086,8 +2075,8 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
ext_info = xcb_get_extension_data(ps->c.c, &xcb_glx_id);
if (ext_info && ext_info->present) {
ps->glx_exists = true;
ps->glx_error = ext_info->first_error;
ps->c.e.has_glx = true;
ps->c.e.glx_error = ext_info->first_error;
}
// Parse configuration file
@ -2179,14 +2168,14 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
// Query X Shape
ext_info = xcb_get_extension_data(ps->c.c, &xcb_shape_id);
if (ext_info && ext_info->present) {
ps->shape_event = ext_info->first_event;
ps->shape_exists = true;
ps->c.e.shape_event = ext_info->first_event;
ps->c.e.has_shape = true;
}
ext_info = xcb_get_extension_data(ps->c.c, &xcb_randr_id);
if (ext_info && ext_info->present) {
ps->randr_exists = true;
ps->randr_event = ext_info->first_event;
ps->c.e.has_randr = true;
ps->c.e.randr_event = ext_info->first_event;
}
ext_info = xcb_get_extension_data(ps->c.c, &xcb_present_id);
@ -2197,7 +2186,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
XCB_PRESENT_MINOR_VERSION),
NULL);
if (r) {
ps->present_exists = true;
ps->c.e.has_present = true;
free(r);
}
}
@ -2205,8 +2194,8 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
// Query X Sync
ext_info = xcb_get_extension_data(ps->c.c, &xcb_sync_id);
if (ext_info && ext_info->present) {
ps->xsync_error = ext_info->first_error;
ps->xsync_event = ext_info->first_event;
ps->c.e.sync_error = ext_info->first_error;
ps->c.e.sync_event = ext_info->first_event;
// Need X Sync 3.1 for fences
auto r = xcb_sync_initialize_reply(
ps->c.c,
@ -2214,13 +2203,13 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
NULL);
if (r && (r->major_version > 3 ||
(r->major_version == 3 && r->minor_version >= 1))) {
ps->xsync_exists = true;
ps->c.e.has_sync = true;
free(r);
}
}
ps->sync_fence = XCB_NONE;
if (ps->xsync_exists) {
if (ps->c.e.has_sync) {
ps->sync_fence = x_new_id(&ps->c);
e = xcb_request_check(
ps->c.c, xcb_sync_create_fence_checked(
@ -2242,7 +2231,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
}
// Query X RandR
if (ps->o.crop_shadow_to_monitor && !ps->randr_exists) {
if (ps->o.crop_shadow_to_monitor && !ps->c.e.has_randr) {
log_fatal("No X RandR extension. crop-shadow-to-monitor cannot be "
"enabled.");
goto err;
@ -2290,7 +2279,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
// Monitor screen changes if vsync_sw is enabled and we are using
// an auto-detected refresh rate, or when X RandR features are enabled
if (ps->randr_exists) {
if (ps->c.e.has_randr) {
xcb_randr_select_input(ps->c.c, ps->c.screen_info->root,
XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);
x_update_monitors_async(&ps->c, &ps->monitors);

View file

@ -391,7 +391,7 @@ void win_process_primary_flags(session_t *ps, struct win *w) {
if (win_check_flags_all(w, WIN_FLAGS_SIZE_STALE)) {
win_on_win_size_change(w, ps->o.shadow_offset_x,
ps->o.shadow_offset_y, ps->o.shadow_radius);
win_update_bounding_shape(&ps->c, w, ps->shape_exists,
win_update_bounding_shape(&ps->c, w, ps->c.e.has_shape,
ps->o.detect_rounded_corners);
win_clear_flags(w, WIN_FLAGS_SIZE_STALE);
@ -1308,7 +1308,7 @@ struct win *win_maybe_allocate(session_t *ps, struct wm_ref *cursor,
(const uint32_t[]){frame_event_mask}));
// Get notification when the shape of a window changes
if (ps->shape_exists) {
if (ps->c.e.has_shape) {
x_set_error_action_ignore(&ps->c, xcb_shape_select_input(ps->c.c, wid, 1));
}

15
src/x.c
View file

@ -64,14 +64,13 @@ static const char *x_error_code_to_string(unsigned long serial, uint8_t major,
#define CASESTRRET2(s) \
case XCB_##s: name = #s; break
// TODO(yshui) separate error code out from session_t
o = error_code - ps->xfixes_error;
o = error_code - ps->c.e.fixes_error;
switch (o) { CASESTRRET2(XFIXES_BAD_REGION); }
o = error_code - ps->damage_error;
o = error_code - ps->c.e.damage_error;
switch (o) { CASESTRRET2(DAMAGE_BAD_DAMAGE); }
o = error_code - ps->render_error;
o = error_code - ps->c.e.render_error;
switch (o) {
CASESTRRET2(RENDER_PICT_FORMAT);
CASESTRRET2(RENDER_PICTURE);
@ -80,8 +79,8 @@ static const char *x_error_code_to_string(unsigned long serial, uint8_t major,
CASESTRRET2(RENDER_GLYPH);
}
if (ps->glx_exists) {
o = error_code - ps->glx_error;
if (ps->c.e.has_glx) {
o = error_code - ps->c.e.glx_error;
switch (o) {
CASESTRRET2(GLX_BAD_CONTEXT);
CASESTRRET2(GLX_BAD_CONTEXT_STATE);
@ -100,8 +99,8 @@ static const char *x_error_code_to_string(unsigned long serial, uint8_t major,
}
}
if (ps->xsync_exists) {
o = error_code - ps->xsync_error;
if (ps->c.e.has_sync) {
o = error_code - ps->c.e.sync_error;
switch (o) {
CASESTRRET(XSyncBadCounter);
CASESTRRET(XSyncBadAlarm);

33
src/x.h
View file

@ -45,6 +45,37 @@ enum x_error_action {
PENDING_REPLY_ACTION_DEBUG_ABORT,
};
struct x_extensions {
/// The X Damage extension's base event number.
int damage_event;
/// The X Damage extension's base error number.
int damage_error;
/// The X Fixes extension's base error number.
int fixes_error;
/// The X GLX extension's presence.
bool has_glx;
/// The X GLX extension's base error number.
int glx_error;
/// The X Present extension's presence.
bool has_present;
/// The X RandR extension's presence.
bool has_randr;
/// The X RandR extension's base event number.
int randr_event;
/// The X Render extension's base error number.
int render_error;
/// The X Shape extension's presence.
bool has_shape;
/// The X Shape extension's base event number.
int shape_event;
/// The X Sync extension's presence.
bool has_sync;
/// The X Sync extension's base event number.
int sync_event;
/// The X Sync extension's base error number.
int sync_error;
};
struct x_connection {
// Public fields
// These are part of the public ABI, changing these
@ -55,6 +86,8 @@ struct x_connection {
Display *dpy;
/// Default screen
int screen;
/// Information about the X extensions.
struct x_extensions e;
// Private fields
/// The list of pending async requests that we have