aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/capture/kms.c67
-rw-r--r--src/capture/xcomposite.c10
-rw-r--r--src/egl.c47
-rw-r--r--src/main.cpp35
-rw-r--r--src/utils.c54
5 files changed, 161 insertions, 52 deletions
diff --git a/src/capture/kms.c b/src/capture/kms.c
index 1616bd7..c677bbb 100644
--- a/src/capture/kms.c
+++ b/src/capture/kms.c
@@ -1,8 +1,10 @@
#include "../../include/capture/kms.h"
#include "../../include/utils.h"
#include "../../include/color_conversion.h"
+#include "../../include/cursor.h"
#include "../../kms/client/kms_client.h"
+#include <X11/Xlib.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -45,6 +47,9 @@ typedef struct {
struct hdr_output_metadata hdr_metadata;
bool hdr_metadata_set;
+
+ gsr_cursor x11_cursor;
+ XEvent xev;
} gsr_capture_kms;
static void gsr_capture_kms_cleanup_kms_fds(gsr_capture_kms *self) {
@@ -79,6 +84,7 @@ static void gsr_capture_kms_stop(gsr_capture_kms *self) {
gsr_capture_kms_cleanup_kms_fds(self);
gsr_kms_client_deinit(&self->kms_client);
+ gsr_cursor_deinit(&self->x11_cursor);
}
static int max_int(int a, int b) {
@@ -151,14 +157,19 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c
if(kms_init_res != 0)
return kms_init_res;
+ const bool is_x11 = gsr_egl_get_display_server(self->params.egl) == GSR_DISPLAY_SERVER_X11;
+ const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
+ if(is_x11)
+ gsr_cursor_init(&self->x11_cursor, self->params.egl, self->params.egl->x11.dpy);
+
MonitorCallbackUserdata monitor_callback_userdata = {
&self->monitor_id,
self->params.display_to_capture, strlen(self->params.display_to_capture),
0,
};
- for_each_active_monitor_output(self->params.egl, GSR_CONNECTION_DRM, monitor_callback, &monitor_callback_userdata);
+ for_each_active_monitor_output(self->params.egl, connection_type, monitor_callback, &monitor_callback_userdata);
- if(!get_monitor_by_name(self->params.egl, GSR_CONNECTION_DRM, self->params.display_to_capture, &monitor)) {
+ if(!get_monitor_by_name(self->params.egl, connection_type, self->params.display_to_capture, &monitor)) {
fprintf(stderr, "gsr error: gsr_capture_kms_start: failed to find monitor by name \"%s\"\n", self->params.display_to_capture);
gsr_capture_kms_stop(self);
return -1;
@@ -168,7 +179,8 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c
self->monitor_rotation = drm_monitor_get_display_server_rotation(self->params.egl, &monitor);
self->capture_pos = monitor.pos;
- if(self->monitor_rotation == GSR_MONITOR_ROT_90 || self->monitor_rotation == GSR_MONITOR_ROT_270) {
+ /* Monitor size is already rotated on x11 when the monitor is rotated, no need to apply it ourselves */
+ if(!is_x11 && (self->monitor_rotation == GSR_MONITOR_ROT_90 || self->monitor_rotation == GSR_MONITOR_ROT_270)) {
self->capture_size.x = monitor.size.y;
self->capture_size.y = monitor.size.x;
} else {
@@ -186,6 +198,16 @@ static int gsr_capture_kms_start(gsr_capture *cap, AVCodecContext *video_codec_c
return 0;
}
+static void gsr_capture_kms_tick(gsr_capture *cap, AVCodecContext *video_codec_context) {
+ (void)video_codec_context;
+ gsr_capture_kms *self = cap->priv;
+
+ while(XPending(self->params.egl->x11.dpy)) {
+ XNextEvent(self->params.egl->x11.dpy, &self->xev);
+ gsr_cursor_update(&self->x11_cursor, &self->xev);
+ }
+}
+
static float monitor_rotation_to_radians(gsr_monitor_rotation rot) {
switch(rot) {
case GSR_MONITOR_ROT_0: return 0.0f;
@@ -238,12 +260,16 @@ static gsr_kms_response_item* find_largest_drm(gsr_kms_response *kms_response) {
return largest_drm;
}
-static gsr_kms_response_item* find_cursor_drm(gsr_kms_response *kms_response) {
+static gsr_kms_response_item* find_cursor_drm(gsr_kms_response *kms_response, uint32_t connector_id) {
+ gsr_kms_response_item *cursor_drm = NULL;
for(int i = 0; i < kms_response->num_items; ++i) {
- if(kms_response->items[i].is_cursor)
- return &kms_response->items[i];
+ if(kms_response->items[i].is_cursor) {
+ cursor_drm = &kms_response->items[i];
+ if(kms_response->items[i].connector_id == connector_id)
+ break;
+ }
}
- return NULL;
+ return cursor_drm;
}
static bool hdr_metadata_is_supported_format(const struct hdr_output_metadata *hdr_metadata) {
@@ -329,7 +355,7 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c
capture_is_combined_plane = true;
}
- cursor_drm_fd = find_cursor_drm(&self->kms_response);
+ cursor_drm_fd = find_cursor_drm(&self->kms_response, drm_fd->connector_id);
if(!drm_fd)
return -1;
@@ -337,6 +363,10 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c
if(!capture_is_combined_plane && cursor_drm_fd && cursor_drm_fd->connector_id != drm_fd->connector_id)
cursor_drm_fd = NULL;
+ const bool is_x11 = gsr_egl_get_display_server(self->params.egl) == GSR_DISPLAY_SERVER_X11;
+ if(is_x11)
+ cursor_drm_fd = NULL;
+
if(drm_fd->has_hdr_metadata && self->params.hdr && hdr_metadata_is_supported_format(&drm_fd->hdr_metadata))
gsr_kms_set_hdr_metadata(self, drm_fd);
@@ -471,6 +501,25 @@ static int gsr_capture_kms_capture(gsr_capture *cap, AVFrame *frame, gsr_color_c
self->params.egl->glDisable(GL_SCISSOR_TEST);
}
+ if(self->params.record_cursor && !cursor_drm_fd && is_x11) {
+ gsr_cursor_tick(&self->x11_cursor, DefaultRootWindow(self->params.egl->x11.dpy));
+
+ const vec2i cursor_pos = {
+ target_x + self->x11_cursor.position.x - self->x11_cursor.hotspot.x - capture_pos.x,
+ target_y + self->x11_cursor.position.y - self->x11_cursor.hotspot.y - capture_pos.y
+ };
+
+ self->params.egl->glEnable(GL_SCISSOR_TEST);
+ self->params.egl->glScissor(target_x, target_y, self->capture_size.x, self->capture_size.y);
+
+ gsr_color_conversion_draw(color_conversion, self->x11_cursor.texture_id,
+ cursor_pos, self->x11_cursor.size,
+ (vec2i){0, 0}, self->x11_cursor.size,
+ 0.0f, false);
+
+ self->params.egl->glDisable(GL_SCISSOR_TEST);
+ }
+
//self->params.egl->glFlush();
//self->params.egl->glFinish();
@@ -566,7 +615,7 @@ gsr_capture* gsr_capture_kms_create(const gsr_capture_kms_params *params) {
*cap = (gsr_capture) {
.start = gsr_capture_kms_start,
- .tick = NULL,
+ .tick = gsr_capture_kms_tick,
.should_stop = gsr_capture_kms_should_stop,
.capture = gsr_capture_kms_capture,
.capture_end = gsr_capture_kms_capture_end,
diff --git a/src/capture/xcomposite.c b/src/capture/xcomposite.c
index a81c19f..899ffe0 100644
--- a/src/capture/xcomposite.c
+++ b/src/capture/xcomposite.c
@@ -325,11 +325,6 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, AVFrame *frame, gsr_
const int target_x = max_int(0, frame->width / 2 - self->texture_size.x / 2);
const int target_y = max_int(0, frame->height / 2 - self->texture_size.y / 2);
- const vec2i cursor_pos = {
- target_x + self->cursor.position.x - self->cursor.hotspot.x,
- target_y + self->cursor.position.y - self->cursor.hotspot.y
- };
-
gsr_color_conversion_draw(color_conversion, window_texture_get_opengl_texture_id(&self->window_texture),
(vec2i){target_x, target_y}, self->texture_size,
(vec2i){0, 0}, self->texture_size,
@@ -338,6 +333,11 @@ static int gsr_capture_xcomposite_capture(gsr_capture *cap, AVFrame *frame, gsr_
if(self->params.record_cursor && self->cursor.visible) {
gsr_cursor_tick(&self->cursor, self->window);
+ const vec2i cursor_pos = {
+ target_x + self->cursor.position.x - self->cursor.hotspot.x,
+ target_y + self->cursor.position.y - self->cursor.hotspot.y
+ };
+
self->params.egl->glEnable(GL_SCISSOR_TEST);
self->params.egl->glScissor(target_x, target_y, self->texture_size.x, self->texture_size.y);
diff --git a/src/egl.c b/src/egl.c
index 3dda33d..2f5230f 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -1,16 +1,17 @@
#include "../include/egl.h"
#include "../include/library_loader.h"
#include "../include/utils.h"
+
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <assert.h>
+#include <unistd.h>
+#include <sys/capability.h>
#include <wayland-client.h>
#include <wayland-egl.h>
-#include <unistd.h>
-#include <sys/capability.h>
// TODO: rename gsr_egl to something else since this includes both egl and glx and in the future maybe vulkan too
@@ -93,7 +94,7 @@ static void registry_add_object(void *data, struct wl_registry *registry, uint32
}
if(egl->wayland.num_outputs == GSR_MAX_OUTPUTS) {
- fprintf(stderr, "gsr warning: reached maximum outputs (32), ignoring output %u\n", name);
+ fprintf(stderr, "gsr warning: reached maximum outputs (%d), ignoring output %u\n", GSR_MAX_OUTPUTS, name);
return;
}
@@ -134,6 +135,26 @@ static void reset_cap_nice(void) {
cap_free(caps);
}
+static void store_x11_monitor(const gsr_monitor *monitor, void *userdata) {
+ gsr_egl *egl = userdata;
+ if(egl->x11.num_outputs == GSR_MAX_OUTPUTS) {
+ fprintf(stderr, "gsr warning: reached maximum outputs (%d), ignoring output %s\n", GSR_MAX_OUTPUTS, monitor->name);
+ return;
+ }
+
+ char *monitor_name = strdup(monitor->name);
+ if(!monitor_name)
+ return;
+
+ const int index = egl->x11.num_outputs;
+ egl->x11.outputs[index].name = monitor_name;
+ egl->x11.outputs[index].pos = monitor->pos;
+ egl->x11.outputs[index].size = monitor->size;
+ egl->x11.outputs[index].connector_id = monitor->connector_id;
+ egl->x11.outputs[index].rotation = monitor->rotation;
+ ++egl->x11.num_outputs;
+}
+
#define GLX_DRAWABLE_TYPE 0x8010
#define GLX_RENDER_TYPE 0x8011
#define GLX_RGBA_BIT 0x00000001
@@ -271,6 +292,11 @@ static bool gsr_egl_create_window(gsr_egl *self, bool wayland) {
goto fail;
}
+ if(!wayland) {
+ self->x11.num_outputs = 0;
+ for_each_active_monitor_output_x11_not_cached(self->x11.dpy, store_x11_monitor, self);
+ }
+
reset_cap_nice();
return true;
@@ -587,6 +613,14 @@ void gsr_egl_unload(gsr_egl *self) {
self->x11.window = None;
}
+ for(int i = 0; i < self->x11.num_outputs; ++i) {
+ if(self->x11.outputs[i].name) {
+ free(self->x11.outputs[i].name);
+ self->x11.outputs[i].name = NULL;
+ }
+ }
+ self->x11.num_outputs = 0;
+
if(self->wayland.window) {
wl_egl_window_destroy(self->wayland.window);
self->wayland.window = NULL;
@@ -658,3 +692,10 @@ void gsr_egl_swap_buffers(gsr_egl *self) {
self->glXSwapBuffers(self->x11.dpy, self->x11.window);
}
}
+
+gsr_display_server gsr_egl_get_display_server(const gsr_egl *egl) {
+ if(egl->wayland.dpy)
+ return GSR_DISPLAY_SERVER_WAYLAND;
+ else
+ return GSR_DISPLAY_SERVER_X11;
+}
diff --git a/src/main.cpp b/src/main.cpp
index 760dcd6..cd1ec5d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1650,7 +1650,7 @@ static bool is_xwayland(Display *display) {
return true;
bool xwayland_found = false;
- for_each_active_monitor_output_x11(display, xwayland_check_callback, &xwayland_found);
+ for_each_active_monitor_output_x11_not_cached(display, xwayland_check_callback, &xwayland_found);
return xwayland_found;
}
@@ -1716,7 +1716,7 @@ typedef struct {
static void output_monitor_info(const gsr_monitor *monitor, void *userdata) {
const capture_options_callback *options = (capture_options_callback*)userdata;
- if(monitor_capture_use_drm(options->egl, options->wayland)) {
+ if(options->wayland && monitor_capture_use_drm(options->egl, options->wayland)) {
vec2i monitor_size = monitor->size;
const gsr_monitor_rotation rot = drm_monitor_get_display_server_rotation(options->egl, monitor);
if(rot == GSR_MONITOR_ROT_90 || rot == GSR_MONITOR_ROT_270)
@@ -1737,7 +1737,9 @@ static void list_supported_capture_options(gsr_egl *egl, bool wayland) {
options.wayland = wayland;
options.egl = egl;
if(monitor_capture_use_drm(egl, wayland)) {
- for_each_active_monitor_output(egl, GSR_CONNECTION_DRM, output_monitor_info, &options);
+ const bool is_x11 = gsr_egl_get_display_server(egl) == GSR_DISPLAY_SERVER_X11;
+ const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
+ for_each_active_monitor_output(egl, connection_type, output_monitor_info, &options);
} else {
puts("screen"); // All monitors in one, only available on Nvidia X11
for_each_active_monitor_output(egl, GSR_CONNECTION_X11, output_monitor_info, &options);
@@ -1775,10 +1777,11 @@ static void info_command() {
if(!wayland)
wayland = is_xwayland(dpy);
- if(!wayland) {
+ if(!wayland && is_using_prime_run()) {
// Disable prime-run and similar options as it doesn't work, the monitor to capture has to be run on the same device.
// This is fine on wayland since nvidia uses drm interface there and the monitor query checks the monitors connected
// to the drm device.
+ fprintf(stderr, "Warning: use of prime-run on X11 is not supported. Disabling prime-run\n");
disable_prime_run();
}
@@ -1890,10 +1893,13 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
#endif
} else if(contains_non_hex_number(window_str)) {
if(monitor_capture_use_drm(egl, wayland)) {
+ const bool is_x11 = gsr_egl_get_display_server(egl) == GSR_DISPLAY_SERVER_X11;
+ const gsr_connection_type connection_type = is_x11 ? GSR_CONNECTION_X11 : GSR_CONNECTION_DRM;
+
if(strcmp(window_str, "screen") == 0) {
FirstOutputCallback first_output;
first_output.output_name = NULL;
- for_each_active_monitor_output(egl, GSR_CONNECTION_DRM, get_first_output, &first_output);
+ for_each_active_monitor_output(egl, connection_type, get_first_output, &first_output);
if(first_output.output_name) {
window_str = first_output.output_name;
@@ -1901,14 +1907,14 @@ static gsr_capture* create_capture_impl(const char *window_str, const char *scre
fprintf(stderr, "Error: no usable output found\n");
_exit(1);
}
- }
-
- gsr_monitor gmon;
- if(!get_monitor_by_name(egl, GSR_CONNECTION_DRM, window_str, &gmon)) {
- fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str);
- fprintf(stderr, " \"screen\"\n");
- for_each_active_monitor_output(egl, GSR_CONNECTION_DRM, monitor_output_callback_print, NULL);
- _exit(1);
+ } else {
+ gsr_monitor gmon;
+ if(!get_monitor_by_name(egl, connection_type, window_str, &gmon)) {
+ fprintf(stderr, "gsr error: display \"%s\" not found, expected one of:\n", window_str);
+ fprintf(stderr, " \"screen\"\n");
+ for_each_active_monitor_output(egl, connection_type, monitor_output_callback_print, NULL);
+ _exit(1);
+ }
}
} else {
if(strcmp(window_str, "screen") != 0 && strcmp(window_str, "screen-direct") != 0 && strcmp(window_str, "screen-direct-force") != 0) {
@@ -2464,10 +2470,11 @@ int main(int argc, char **argv) {
if(!wayland)
wayland = is_xwayland(dpy);
- if(!wayland) {
+ if(!wayland && is_using_prime_run()) {
// Disable prime-run and similar options as it doesn't work, the monitor to capture has to be run on the same device.
// This is fine on wayland since nvidia uses drm interface there and the monitor query checks the monitors connected
// to the drm device.
+ fprintf(stderr, "Warning: use of prime-run on X11 is not supported. Disabling prime-run\n");
disable_prime_run();
}
diff --git a/src/utils.c b/src/utils.c
index 28c66e0..7cd57cb 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -9,6 +9,7 @@
#include <sys/stat.h>
#include <errno.h>
#include <assert.h>
+#include <dirent.h>
#include <xf86drmMode.h>
#include <xf86drm.h>
@@ -24,6 +25,16 @@ double clock_get_monotonic_seconds(void) {
return (double)ts.tv_sec + (double)ts.tv_nsec * 0.000000001;
}
+static gsr_monitor_rotation wayland_transform_to_gsr_rotation(int32_t rot) {
+ switch(rot) {
+ case 0: return GSR_MONITOR_ROT_0;
+ case 1: return GSR_MONITOR_ROT_90;
+ case 2: return GSR_MONITOR_ROT_180;
+ case 3: return GSR_MONITOR_ROT_270;
+ }
+ return GSR_MONITOR_ROT_0;
+}
+
static const XRRModeInfo* get_mode_info(const XRRScreenResources *sr, RRMode id) {
for(int i = 0; i < sr->nmode; ++i) {
if(sr->modes[i].id == id)
@@ -42,16 +53,6 @@ static gsr_monitor_rotation x11_rotation_to_gsr_rotation(int rot) {
return GSR_MONITOR_ROT_0;
}
-static gsr_monitor_rotation wayland_transform_to_gsr_rotation(int32_t rot) {
- switch(rot) {
- case 0: return GSR_MONITOR_ROT_0;
- case 1: return GSR_MONITOR_ROT_90;
- case 2: return GSR_MONITOR_ROT_180;
- case 3: return GSR_MONITOR_ROT_270;
- }
- return GSR_MONITOR_ROT_0;
-}
-
static uint32_t x11_output_get_connector_id(Display *dpy, RROutput output, Atom randr_connector_id_atom) {
Atom type = 0;
int format = 0;
@@ -68,7 +69,7 @@ static uint32_t x11_output_get_connector_id(Display *dpy, RROutput output, Atom
return result;
}
-void for_each_active_monitor_output_x11(Display *display, active_monitor_callback callback, void *userdata) {
+void for_each_active_monitor_output_x11_not_cached(Display *display, active_monitor_callback callback, void *userdata) {
XRRScreenResources *screen_res = XRRGetScreenResources(display, DefaultRootWindow(display));
if(!screen_res)
return;
@@ -83,15 +84,12 @@ void for_each_active_monitor_output_x11(Display *display, active_monitor_callbac
if(crt_info && crt_info->mode) {
const XRRModeInfo *mode_info = get_mode_info(screen_res, crt_info->mode);
if(mode_info && out_info->nameLen < (int)sizeof(display_name)) {
- memcpy(display_name, out_info->name, out_info->nameLen);
- display_name[out_info->nameLen] = '\0';
-
+ snprintf(display_name, sizeof(display_name), "%.*s", (int)out_info->nameLen, out_info->name);
const gsr_monitor monitor = {
.name = display_name,
.name_len = out_info->nameLen,
.pos = { .x = crt_info->x, .y = crt_info->y },
.size = { .x = (int)crt_info->width, .y = (int)crt_info->height },
- .crt_info = crt_info,
.connector_id = x11_output_get_connector_id(display, screen_res->outputs[i], randr_connector_id_atom),
.rotation = x11_rotation_to_gsr_rotation(crt_info->rotation),
.monitor_identifier = 0
@@ -109,6 +107,22 @@ void for_each_active_monitor_output_x11(Display *display, active_monitor_callbac
XRRFreeScreenResources(screen_res);
}
+void for_each_active_monitor_output_x11(const gsr_egl *egl, active_monitor_callback callback, void *userdata) {
+ for(int i = 0; i < egl->x11.num_outputs; ++i) {
+ const gsr_x11_output *output = &egl->x11.outputs[i];
+ const gsr_monitor monitor = {
+ .name = output->name,
+ .name_len = strlen(output->name),
+ .pos = output->pos,
+ .size = output->size,
+ .connector_id = output->connector_id,
+ .rotation = output->rotation,
+ .monitor_identifier = 0
+ };
+ callback(&monitor, userdata);
+ }
+}
+
typedef struct {
int type;
int count;
@@ -192,7 +206,6 @@ static void for_each_active_monitor_output_wayland(const gsr_egl *egl, active_mo
.name_len = strlen(output->name),
.pos = { .x = output->pos.x, .y = output->pos.y },
.size = { .x = output->size.x, .y = output->size.y },
- .crt_info = NULL,
.connector_id = 0,
.rotation = wayland_transform_to_gsr_rotation(output->transform),
.monitor_identifier = connector_type ? monitor_identifier_from_type_and_count(connector_type_index, connector_type->count_active) : 0
@@ -240,12 +253,11 @@ static void for_each_active_monitor_output_drm(const gsr_egl *egl, active_monito
if(connector_type && crtc_id > 0 && crtc && connection_name_len + 5 < (int)sizeof(display_name)) {
const int display_name_len = snprintf(display_name, sizeof(display_name), "%s-%d", connection_name, connector_type->count);
const int connector_type_index_name = get_connector_type_by_name(display_name);
- const gsr_monitor monitor = {
+ gsr_monitor monitor = {
.name = display_name,
.name_len = display_name_len,
.pos = { .x = crtc->x, .y = crtc->y },
.size = { .x = (int)crtc->width, .y = (int)crtc->height },
- .crt_info = NULL,
.connector_id = connector->connector_id,
.rotation = GSR_MONITOR_ROT_0,
.monitor_identifier = connector_type_index_name != -1 ? monitor_identifier_from_type_and_count(connector_type_index_name, connector_type->count_active) : 0
@@ -267,7 +279,7 @@ static void for_each_active_monitor_output_drm(const gsr_egl *egl, active_monito
void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata) {
switch(connection_type) {
case GSR_CONNECTION_X11:
- for_each_active_monitor_output_x11(egl->x11.dpy, callback, userdata);
+ for_each_active_monitor_output_x11(egl, callback, userdata);
break;
case GSR_CONNECTION_WAYLAND:
for_each_active_monitor_output_wayland(egl, callback, userdata);
@@ -329,7 +341,7 @@ static void get_monitor_by_connector_id_callback(const gsr_monitor *monitor, voi
}
gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor) {
- if(egl->wayland.dpy) {
+ if(gsr_egl_get_display_server(egl) == GSR_DISPLAY_SERVER_WAYLAND) {
{
get_monitor_by_connector_id_userdata userdata;
userdata.monitor = monitor;
@@ -352,7 +364,7 @@ gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl,
userdata.monitor = monitor;
userdata.rotation = GSR_MONITOR_ROT_0;
userdata.match_found = false;
- for_each_active_monitor_output_x11(egl->x11.dpy, get_monitor_by_connector_id_callback, &userdata);
+ for_each_active_monitor_output_x11(egl, get_monitor_by_connector_id_callback, &userdata);
return userdata.rotation;
}