xwayland: search for a render node to use
wl_drm's protocol "device" event provides the path to the DRM device,
which may not be a render node, thus causing Xwayland to fall back to
DRM authentication which may fail if the user has switched to another
VT while Xwayland is starting.
Search for a render node corresponding to the given DRM device and try
to use it instead, as render nodes do not need DRM authentication and
Xwayland can make use of them if it can find one.
Closes: https://bugs.freedesktop.org/108038
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
(Cherry picked from commit 361894497c
)
This commit is contained in:
parent
87491ced98
commit
bb74db6b38
|
@ -124,6 +124,22 @@ is_fd_render_node(int fd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char
|
||||||
|
is_device_path_render_node (const char *device_path)
|
||||||
|
{
|
||||||
|
char is_render_node;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = open(device_path, O_RDWR | O_CLOEXEC);
|
||||||
|
if (fd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
is_render_node = is_fd_render_node(fd);
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return is_render_node;
|
||||||
|
}
|
||||||
|
|
||||||
static PixmapPtr
|
static PixmapPtr
|
||||||
xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
|
xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
|
||||||
int depth)
|
int depth)
|
||||||
|
@ -611,14 +627,80 @@ static const dri3_screen_info_rec xwl_dri3_info = {
|
||||||
.get_drawable_modifiers = glamor_get_drawable_modifiers,
|
.get_drawable_modifiers = glamor_get_drawable_modifiers,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_render_node_path_for_device(const drmDevicePtr drm_device,
|
||||||
|
const char *device_path)
|
||||||
|
{
|
||||||
|
char *render_node_path = NULL;
|
||||||
|
char device_found = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < DRM_NODE_MAX; i++) {
|
||||||
|
if ((drm_device->available_nodes & (1 << i)) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp (device_path, drm_device->nodes[i]))
|
||||||
|
device_found = 1;
|
||||||
|
|
||||||
|
if (is_device_path_render_node(drm_device->nodes[i]))
|
||||||
|
render_node_path = drm_device->nodes[i];
|
||||||
|
|
||||||
|
if (device_found && render_node_path)
|
||||||
|
return render_node_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_render_node_path(const char *device_path)
|
||||||
|
{
|
||||||
|
drmDevicePtr *devices = NULL;
|
||||||
|
char *render_node_path = NULL;
|
||||||
|
int i, n_devices, max_devices;
|
||||||
|
|
||||||
|
max_devices = drmGetDevices2(0, NULL, 0);
|
||||||
|
if (max_devices <= 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
devices = calloc(max_devices, sizeof(drmDevicePtr));
|
||||||
|
if (!devices)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
n_devices = drmGetDevices2(0, devices, max_devices);
|
||||||
|
if (n_devices < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for (i = 0; i < n_devices; i++) {
|
||||||
|
const char *node_path = get_render_node_path_for_device(devices[i],
|
||||||
|
device_path);
|
||||||
|
if (node_path) {
|
||||||
|
render_node_path = strdup(node_path);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(devices);
|
||||||
|
return render_node_path;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
|
xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
|
||||||
{
|
{
|
||||||
struct xwl_screen *xwl_screen = data;
|
struct xwl_screen *xwl_screen = data;
|
||||||
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
drm_magic_t magic;
|
drm_magic_t magic;
|
||||||
|
char *render_node_path = NULL;
|
||||||
|
|
||||||
|
if (!is_device_path_render_node(device))
|
||||||
|
render_node_path = get_render_node_path(device);
|
||||||
|
|
||||||
|
if (render_node_path)
|
||||||
|
xwl_gbm->device_name = render_node_path;
|
||||||
|
else
|
||||||
xwl_gbm->device_name = strdup(device);
|
xwl_gbm->device_name = strdup(device);
|
||||||
|
|
||||||
if (!xwl_gbm->device_name) {
|
if (!xwl_gbm->device_name) {
|
||||||
xwl_glamor_gbm_cleanup(xwl_screen);
|
xwl_glamor_gbm_cleanup(xwl_screen);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue