diff options
author | Julien Ropé <jrope@redhat.com> | 2020-04-29 16:31:58 +0200 |
---|---|---|
committer | Julien Ropé <jrope@redhat.com> | 2020-10-19 17:58:54 +0200 |
commit | 4c8009068115b6f89491e0e3e108d38084b2417a (patch) | |
tree | 68803c938f7e04d7399b1c884c72d452df8141d2 | |
parent | d92f37ae06aafa77b8bc27a458c449c28d0d5f09 (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.c | 24 | ||||
-rw-r--r-- | src/vdagent/device-info.h | 3 | ||||
-rw-r--r-- | src/vdagent/display.c | 56 | ||||
-rw-r--r-- | src/vdagent/x11-randr.c | 5 | ||||
-rw-r--r-- | src/vdagent/x11.h | 3 |
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 |