diff options
author | Keith Packard <keithp@keithp.com> | 2018-01-18 18:07:29 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2018-01-24 10:51:08 +1100 |
commit | aead4a60c29857047a3493eadee4b6bf3e997b72 (patch) | |
tree | 8205867e56798f09dbd5a885700593849ea41acf | |
parent | 9e8d2a9450c69f86024d62d3ed0525c744c0717e (diff) |
modesetting: Allow a DRM fd to be passed through XF86_VIDEO_MODESETTING_FDdrm-lease-v2
This lets an application open a suitable DRM device and pass the file
descriptor to the mode setting driver through an environment variable.
There's a companion application, xlease, which creates a DRM master by
leasing an output from another X server. That is available at
git clone git://people.freedesktop.org/~keithp/xlease
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 29 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.h | 1 |
2 files changed, 29 insertions, 1 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 2e4c43b5b..1181effe7 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -195,10 +195,27 @@ modesettingEntPtr ms_ent_priv(ScrnInfoPtr scrn) } static int +get_passed_fd(void) +{ + char *fdstr = getenv("XF86_VIDEO_MODESETTING_FD"); + + if (fdstr) { + char *endptr; + int fd = strtol(fdstr, &endptr, 10); + if (endptr != fdstr && *endptr == '\0') + return dup(fd); + } + return -1; +} + +static int open_hw(const char *dev) { int fd; + if ((fd = get_passed_fd()) >= 0) + return fd; + if (dev) fd = open(dev, O_RDWR, 0); else { @@ -822,6 +839,12 @@ ms_get_drm_master_fd(ScrnInfoPtr pScrn) return TRUE; } + ms->fd_passed = FALSE; + if ((ms->fd = get_passed_fd()) >= 0) { + ms->fd_passed = TRUE; + return TRUE; + } + #ifdef XSERVER_PLATFORM_BUS if (pEnt->location.type == BUS_PLATFORM) { if (pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD) @@ -1494,6 +1517,9 @@ SetMaster(ScrnInfoPtr pScrn) (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)) return TRUE; + if (ms->fd_passed) + return TRUE; + ret = drmSetMaster(ms->fd); if (ret) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmSetMaster failed: %s\n", @@ -1745,7 +1771,8 @@ LeaveVT(ScrnInfoPtr pScrn) (ms->pEnt->location.id.plat->flags & XF86_PDEV_SERVER_FD)) return; - drmDropMaster(ms->fd); + if (!ms->fd_passed) + drmDropMaster(ms->fd); } /* diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h index fe835918b..6be51e01b 100644 --- a/hw/xfree86/drivers/modesetting/driver.h +++ b/hw/xfree86/drivers/modesetting/driver.h @@ -84,6 +84,7 @@ struct ms_drm_queue { typedef struct _modesettingRec { int fd; + Bool fd_passed; int Chipset; EntityInfoPtr pEnt; |