summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Ropé <jrope@redhat.com>2020-04-29 16:31:58 +0200
committerJulien Ropé <jrope@redhat.com>2020-10-19 17:58:54 +0200
commit4c8009068115b6f89491e0e3e108d38084b2417a (patch)
tree68803c938f7e04d7399b1c884c72d452df8141d2
parentd92f37ae06aafa77b8bc27a458c449c28d0d5f09 (diff)
Split the "lookup_xrandr_output_for_device_info()" function to reuse
some of it with different backends. Most display drivers will number their outputs starting with "1", but some (like older QXL drivers) will start from 0. As we need to map device names with SPICE display IDs, we need to know what to expect. The logic that finds whether we have a O-based index or not is independent from the backend, and can be reused outside of the X11 implementation. This commit separates this logic for that purpose, to prevent code duplication. - create the has_zero_based_display_id() function to call whatever the backend, and learn whether our IDs should be decremented or not. Its code is taken out of lookup_xrandr_output_for_device_info() - keep the lookup_xrandr_output_for_device_info() for x11 implementation - add parameters to some functions to give them the information that IDs should be decremented because of the 0-based index. Signed-off-by: Julien Ropé <jrope@redhat.com> Acked-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--src/vdagent/device-info.c24
-rw-r--r--src/vdagent/device-info.h3
-rw-r--r--src/vdagent/display.c56
-rw-r--r--src/vdagent/x11-randr.c5
-rw-r--r--src/vdagent/x11.h3
5 files changed, 63 insertions, 28 deletions
diff --git a/src/vdagent/device-info.c b/src/vdagent/device-info.c
index 8cf72c9..f07de03 100644
--- a/src/vdagent/device-info.c
+++ b/src/vdagent/device-info.c
@@ -482,32 +482,12 @@ int get_connector_name_for_device_info(VDAgentDeviceDisplayInfo *device_info,
bool lookup_xrandr_output_for_device_info(VDAgentDeviceDisplayInfo *device_info,
Display *xdisplay,
XRRScreenResources *xres,
- RROutput *output_id)
+ RROutput *output_id,
+ bool has_virtual_zero_display)
{
char expected_name[100];
int ret;
- // Older QXL drivers numbered their outputs starting with
- // 0. This contrasts with most drivers who start numbering
- // outputs with 1. In this case, the expected drm connector
- // name will need to be decremented before comparing to the
- // xrandr output name
- bool has_virtual_zero_display = false;
- for (int i = 0; i < xres->noutput; ++i) {
- XRROutputInfo *oinfo = XRRGetOutputInfo(xdisplay, xres, xres->outputs[i]);
- if (!oinfo) {
- syslog(LOG_WARNING, "Unable to lookup XRandr output info for output %li",
- xres->outputs[i]);
- return false;
- }
- if (strcmp(oinfo->name, "Virtual-0") == 0) {
- has_virtual_zero_display = true;
- XRRFreeOutputInfo(oinfo);
- break;
- }
- XRRFreeOutputInfo(oinfo);
- }
-
ret = get_connector_name_for_device_info(device_info, expected_name, sizeof(expected_name),
has_virtual_zero_display);
switch (ret) {
diff --git a/src/vdagent/device-info.h b/src/vdagent/device-info.h
index d4d8cbd..f90fbe2 100644
--- a/src/vdagent/device-info.h
+++ b/src/vdagent/device-info.h
@@ -27,7 +27,8 @@ struct vdagent_x11;
bool lookup_xrandr_output_for_device_info(VDAgentDeviceDisplayInfo *device_info,
Display *xdisplay,
XRRScreenResources *xres,
- RROutput *output_id);
+ RROutput *output_id,
+ bool has_virtual_zero_display);
int get_connector_name_for_device_info(VDAgentDeviceDisplayInfo *device_info,
char *expected_name, size_t name_size,
diff --git a/src/vdagent/display.c b/src/vdagent/display.c
index b82db5c..d556f92 100644
--- a/src/vdagent/display.c
+++ b/src/vdagent/display.c
@@ -212,6 +212,57 @@ gboolean vdagent_display_has_icons_on_desktop(VDAgentDisplay *display)
return FALSE;
}
+static bool has_zero_based_display_id(VDAgentDisplay *display)
+{
+ // Older QXL drivers numbered their outputs starting with
+ // 0. This contrasts with most drivers who start numbering
+ // outputs with 1. In this case, the expected drm connector
+ // name will need to be decremented before comparing to the
+ // display manager output name
+ bool ret = false;
+#ifdef USE_GTK_FOR_MONITORS
+ GdkDisplay *gdk_display = gdk_display_get_default();
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display)) {
+ gdk_display_sync(gdk_display);
+
+ GListModel *monitors = gdk_display_get_monitors(gdk_display);
+ int screen_count = g_list_model_get_n_items(monitors);
+ for (int i = 0; i < screen_count; i++) {
+ GdkMonitor *monitor = (GdkMonitor *)g_list_model_get_item(monitors, i);
+ const char *name = gdk_monitor_get_connector(monitor);
+ if (!name) {
+ continue;
+ }
+
+ if (strcmp(name, "Virtual-0") == 0) {
+ ret = true;
+ break;
+ }
+ }
+ }
+ else // otherwise, use the X11 code (below)
+#endif
+ {
+ XRRScreenResources *xres = display->x11->randr.res;
+ Display *xdisplay = display->x11->display;
+ for (int i = 0; i < xres->noutput; ++i) {
+ XRROutputInfo *oinfo = XRRGetOutputInfo(xdisplay, xres, xres->outputs[i]);
+ if (!oinfo) {
+ syslog(LOG_WARNING, "Unable to lookup XRandr output info for output %li",
+ xres->outputs[i]);
+ return false;
+ }
+ if (strcmp(oinfo->name, "Virtual-0") == 0) {
+ ret = true;
+ XRRFreeOutputInfo(oinfo);
+ break;
+ }
+ XRRFreeOutputInfo(oinfo);
+ }
+ }
+ return ret;
+}
+
// handle the device info message from the server. This will allow us to
// maintain a mapping from spice display id to xrandr output
void vdagent_display_handle_graphics_device_info(VDAgentDisplay *display, uint8_t *data,
@@ -221,6 +272,7 @@ void vdagent_display_handle_graphics_device_info(VDAgentDisplay *display, uint8_
VDAgentDeviceDisplayInfo *device_display_info = graphics_device_info->display_info;
void *buffer_end = data + size;
+ bool decrement_id = has_zero_based_display_id(display);
syslog(LOG_INFO, "Received Graphics Device Info:");
@@ -246,7 +298,7 @@ void vdagent_display_handle_graphics_device_info(VDAgentDisplay *display, uint8_
// Get the expected connector name from hardware info. Store it with the SPICE display ID.
char expected_name[100];
int ret = get_connector_name_for_device_info(device_display_info, expected_name,
- sizeof(expected_name), false);
+ sizeof(expected_name), decrement_id);
if (ret == 0) {
g_hash_table_insert(display->connector_mapping,
g_strdup(expected_name),
@@ -258,7 +310,7 @@ void vdagent_display_handle_graphics_device_info(VDAgentDisplay *display, uint8_
else
// under X11, use the X11 API
#endif
- vdagent_x11_handle_device_display_info(display->x11, device_display_info);
+ vdagent_x11_handle_device_display_info(display->x11, device_display_info, decrement_id);
device_display_info = (VDAgentDeviceDisplayInfo*) ((char*) device_display_info +
sizeof(VDAgentDeviceDisplayInfo) + device_display_info->device_address_len);
diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c
index 145e75a..cac9643 100644
--- a/src/vdagent/x11-randr.c
+++ b/src/vdagent/x11-randr.c
@@ -779,11 +779,12 @@ static void dump_monitors_config(struct vdagent_x11 *x11,
// handle the device info message from the server. This will allow us to
// maintain a mapping from spice display id to xrandr output
void vdagent_x11_handle_device_display_info(struct vdagent_x11 *x11,
- VDAgentDeviceDisplayInfo *device_display_info)
+ VDAgentDeviceDisplayInfo *device_display_info,
+ gboolean has_virtual_zero_display)
{
RROutput x_output;
if (lookup_xrandr_output_for_device_info(device_display_info, x11->display,
- x11->randr.res, &x_output)) {
+ x11->randr.res, &x_output, has_virtual_zero_display)) {
syslog(LOG_INFO, "Adding graphics device info: channel_id: %u monitor_id: "
"%u device_address: %s, device_display_id: %u xrandr output ID: %lu",
device_display_info->channel_id,
diff --git a/src/vdagent/x11.h b/src/vdagent/x11.h
index a75638c..45018bd 100644
--- a/src/vdagent/x11.h
+++ b/src/vdagent/x11.h
@@ -53,6 +53,7 @@ void vdagent_x11_client_disconnected(struct vdagent_x11 *x11);
gchar *vdagent_x11_get_wm_name(struct vdagent_x11 *x11);
void vdagent_x11_handle_device_display_info(struct vdagent_x11 *x11,
- VDAgentDeviceDisplayInfo *device_display_info);
+ VDAgentDeviceDisplayInfo *device_display_info,
+ gboolean has_virtual_zero_display);
#endif