Skip to content

Commit

Permalink
core: move x extensions' initialization into a separate function
Browse files Browse the repository at this point in the history
  • Loading branch information
absolutelynothelix committed May 19, 2024
1 parent 7ff668d commit 2a1b74e
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 115 deletions.
117 changes: 2 additions & 115 deletions src/picom.c
Original file line number Diff line number Diff line change
Expand Up @@ -2085,8 +2085,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
ps->root_width = ps->c.screen_info->width_in_pixels;
ps->root_height = ps->c.screen_info->height_in_pixels;

const xcb_query_extension_reply_t *ext_info;

// Start listening to events on root earlier to catch all possible
// root geometry changes
auto e = xcb_request_check(
Expand All @@ -2100,65 +2098,9 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
free(e);
}

xcb_prefetch_extension_data(ps->c.c, &xcb_render_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_composite_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_damage_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_shape_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_xfixes_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_randr_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_present_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_sync_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_glx_id);
xcb_prefetch_extension_data(ps->c.c, &xcb_dpms_id);

ext_info = xcb_get_extension_data(ps->c.c, &xcb_render_id);
if (!ext_info || !ext_info->present) {
log_fatal("No render extension");
exit(1);
}
ps->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) {
log_fatal("No composite extension");
exit(1);
}

{
xcb_composite_query_version_reply_t *reply = xcb_composite_query_version_reply(
ps->c.c,
xcb_composite_query_version(ps->c.c, XCB_COMPOSITE_MAJOR_VERSION,
XCB_COMPOSITE_MINOR_VERSION),
NULL);

if (!reply || (reply->major_version == 0 && reply->minor_version < 2)) {
log_fatal("Your X server doesn't have Composite >= 0.2 support, "
"we cannot proceed.");
exit(1);
}
free(reply);
}

ext_info = xcb_get_extension_data(ps->c.c, &xcb_damage_id);
if (!ext_info || !ext_info->present) {
log_fatal("No damage extension");
exit(1);
}
ps->e.damage_event = ext_info->first_event;
ps->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);

ext_info = xcb_get_extension_data(ps->c.c, &xcb_xfixes_id);
if (!ext_info || !ext_info->present) {
log_fatal("No XFixes extension");
exit(1);
if (!x_extensions_init(ps->c.c, &ps->e)) {
goto err;
}
ps->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);

ps->damage_ring.x_region = x_new_id(&ps->c);
if (!XCB_AWAIT_VOID(xcb_xfixes_create_region, ps->c.c, ps->damage_ring.x_region,
Expand All @@ -2167,18 +2109,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
goto err;
}

ext_info = xcb_get_extension_data(ps->c.c, &xcb_glx_id);
if (ext_info && ext_info->present) {
ps->e.has_glx = true;
ps->e.glx_error = ext_info->first_error;
}

ext_info = xcb_get_extension_data(ps->c.c, &xcb_dpms_id);
ps->e.has_dpms = ext_info && ext_info->present;
if (!ps->e.has_dpms) {
log_warn("No DPMS extension");
}

// Parse configuration file
char *config_file_to_free = NULL;
config_file = config_file_to_free = parse_config(&ps->o, config_file);
Expand Down Expand Up @@ -2247,49 +2177,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
sum_kernel_preprocess((conv *)ps->shadow_context);
}

// Query X Shape
ext_info = xcb_get_extension_data(ps->c.c, &xcb_shape_id);
if (ext_info && ext_info->present) {
ps->e.shape_event = ext_info->first_event;
ps->e.has_shape = true;
}

ext_info = xcb_get_extension_data(ps->c.c, &xcb_randr_id);
if (ext_info && ext_info->present) {
ps->e.has_randr = true;
ps->e.randr_event = ext_info->first_event;
}

ext_info = xcb_get_extension_data(ps->c.c, &xcb_present_id);
if (ext_info && ext_info->present) {
auto r = xcb_present_query_version_reply(
ps->c.c,
xcb_present_query_version(ps->c.c, XCB_PRESENT_MAJOR_VERSION,
XCB_PRESENT_MINOR_VERSION),
NULL);
if (r) {
ps->e.has_present = true;
free(r);
}
}

// Query X Sync
ext_info = xcb_get_extension_data(ps->c.c, &xcb_sync_id);
if (ext_info && ext_info->present) {
ps->e.sync_error = ext_info->first_error;
ps->e.sync_event = ext_info->first_event;
// Need X Sync 3.1 for fences
auto r = xcb_sync_initialize_reply(
ps->c.c,
xcb_sync_initialize(ps->c.c, XCB_SYNC_MAJOR_VERSION, XCB_SYNC_MINOR_VERSION),
NULL);
if (r && (r->major_version > 3 ||
(r->major_version == 3 && r->minor_version >= 1))) {
ps->e.has_sync = true;
free(r);
}
}

ps->sync_fence = XCB_NONE;
if (ps->e.has_sync) {
ps->sync_fence = x_new_id(&ps->c);
Expand Down
150 changes: 150 additions & 0 deletions src/x.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,156 @@ void x_connection_init(struct x_connection *c, Display *dpy) {
c->screen_info = xcb_aux_get_screen(c->c, c->screen);
}

///
bool x_extensions_init(xcb_connection_t *c, struct x_extensions *e) {
// Initialize the X Composite extension.
xcb_prefetch_extension_data(c, &xcb_composite_id);

auto r = xcb_get_extension_data(c, &xcb_composite_id);
if (r && r->present) {
auto r1 = xcb_composite_query_version_reply(
c,
xcb_composite_query_version(c, XCB_COMPOSITE_MAJOR_VERSION,
XCB_COMPOSITE_MINOR_VERSION),
NULL);
if (r1) {
if (r1->major_version == 0 && r1->minor_version < 2) {
log_fatal("The X server doesn't support the X composite "
"extension v0.2.");

free(r1);

return false;
}

free(r1);
}
} else {
log_fatal("The X server doesn't have the X Composite extension.");

return false;
}

// Initialize the X Damage extension.
xcb_prefetch_extension_data(c, &xcb_damage_id);

r = xcb_get_extension_data(c, &xcb_damage_id);
if (r && r->present) {
e->damage_event = r->first_event;
e->damage_error = r->first_error;
} else {
log_fatal("The X server doesn't have the X Damage extension.");

return false;
}

// From the X Damage extension's specification:
// "The client must negotiate the version of the extension before executing
// extension requests. Otherwise, the server will return BadRequest for any
// operations other than QueryVersion."
xcb_discard_reply(c, xcb_damage_query_version(c, XCB_DAMAGE_MAJOR_VERSION,
XCB_DAMAGE_MINOR_VERSION)
.sequence);

// Initialize the X DPMS extension.
xcb_prefetch_extension_data(c, &xcb_dpms_id);

r = xcb_get_extension_data(c, &xcb_dpms_id);
if (r && r->present) {
e->has_dpms = true;
} else {
log_warn("The X server doesn't have the X DPMS extension.");
}

// Initialize the X Fixes extension.
xcb_prefetch_extension_data(c, &xcb_xfixes_id);

r = xcb_get_extension_data(c, &xcb_xfixes_id);
if (r && r->present) {
e->fixes_error = r->first_error;
} else {
log_fatal("The X server doesn't have the X Fixes extension.");

return false;
}

// From the X Fixes extension's specification:
// "The client must negotiate the version of the extension before executing
// extension requests. Behavior of the server is undefined otherwise."
xcb_discard_reply(c, xcb_xfixes_query_version(c, XCB_XFIXES_MAJOR_VERSION,
XCB_XFIXES_MINOR_VERSION)
.sequence);

// Initialize the X GLX extension.
xcb_prefetch_extension_data(c, &xcb_glx_id);

r = xcb_get_extension_data(c, &xcb_glx_id);
if (r && r->present) {
e->has_glx = true;
e->glx_error = r->first_error;
}

// Initialize the X Present extension.
xcb_prefetch_extension_data(c, &xcb_present_id);

r = xcb_get_extension_data(c, &xcb_present_id);
if (r && r->present) {
e->has_present = true;
}

// Initialize the X RandR extension.
xcb_prefetch_extension_data(c, &xcb_randr_id);

r = xcb_get_extension_data(c, &xcb_randr_id);
if (r && r->present) {
e->has_randr = true;
e->randr_event = r->first_event;
}

// Initialize the X Render extension.
xcb_prefetch_extension_data(c, &xcb_render_id);

r = xcb_get_extension_data(c, &xcb_render_id);
if (r && r->present) {
e->render_error = r->first_error;
} else {
log_fatal("The X server doesn't have the X Render extension.");

return false;
}

// Initialize the X Shape extension.
xcb_prefetch_extension_data(c, &xcb_shape_id);

r = xcb_get_extension_data(c, &xcb_shape_id);
if (r && r->present) {
e->has_shape = true;
e->shape_event = r->first_event;
}

// Initialize the X Sync extension.
xcb_prefetch_extension_data(c, &xcb_sync_id);

r = xcb_get_extension_data(c, &xcb_sync_id);
if (r && r->present) {
auto r1 = xcb_sync_initialize_reply(
c, xcb_sync_initialize(c, XCB_SYNC_MAJOR_VERSION, XCB_SYNC_MINOR_VERSION),
NULL);
if (r1) {
if ((r1->major_version == 3 && r1->minor_version >= 1) ||
r1->major_version > 3) {
e->has_sync = true;
e->sync_event = r->first_event;
e->sync_error = r->first_error;
}

free(r1);
}
}

return true;
}

/**
* Get a specific attribute of a window.
*
Expand Down
3 changes: 3 additions & 0 deletions src/x.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,9 @@ static inline void attr_unused free_x_connection(struct x_connection *c) {
/// responsible for closing it after `free_x_connection` is called.
void x_connection_init(struct x_connection *c, Display *dpy);

///
bool x_extensions_init(xcb_connection_t *c, struct x_extensions *e);

/// Discard queued pending replies.
///
/// We have received reply with sequence number `sequence`, which means all pending
Expand Down

0 comments on commit 2a1b74e

Please sign in to comment.