Christopher James Halse Rogers
2012-May-23 12:08 UTC
[Nouveau] [PATCH (nouveau)] Add xwayland support
Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers at canonical.com> --- This is mostly just for testing, although it should be safe to apply to nouveau trunk. src/nouveau_dri2.c | 34 +++++++++++ src/nv_driver.c | 163 +++++++++++++++++++++++++++++++++++++++++++++++----- src/nv_type.h | 7 +++ 3 files changed, 191 insertions(+), 13 deletions(-) diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c index 7e47575..cb1a395 100644 --- a/src/nouveau_dri2.c +++ b/src/nouveau_dri2.c @@ -8,6 +8,10 @@ #ifdef DRI2 #include "dri2.h" #endif +#ifdef XORG_WAYLAND +#include <xf86Priv.h> +#include <xwayland.h> +#endif #if defined(DRI2) && DRI2INFOREC_VERSION >= 3 struct nouveau_dri2_buffer { @@ -660,6 +664,32 @@ nouveau_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec, free(flip); } +#ifdef XORG_WAYLAND +static int nouveau_auth_magic(int fd, uint32_t magic) +{ + ScrnInfoPtr pScrn; + NVPtr pNv; + int i; + + /* Not wayland, go stragight to drm */ + if (!xorgWayland) + return drmAuthMagic(fd, magic); + + /* Technically this should actually iterate over xf86Screens. + Since direct access to xf86Screens is going away, though, + we don't bother right now */ + for (i = 0; i < 1; i++) { + pScrn = xf86Screens[i]; + pNv = NVPTR(pScrn); + if (xwl_screen_get_drm_fd(pNv->xwl_screen) == fd) + break; + } + + /* Forward the request to our host */ + return xwl_drm_authenticate(pNv->xwl_screen, magic); +} +#endif + Bool nouveau_dri2_init(ScreenPtr pScreen) { @@ -689,6 +719,10 @@ nouveau_dri2_init(ScreenPtr pScreen) dri2.ScheduleWaitMSC = nouveau_dri2_schedule_wait; dri2.GetMSC = nouveau_dri2_get_msc; +#if DRI2INFOREC_VERSION >= 5 && defined(XORG_WAYLAND) + dri2.AuthMagic = nouveau_auth_magic; +#endif + #if DRI2INFOREC_VERSION >= 6 dri2.SwapLimitValidate = nouveau_dri2_swap_limit_validate; #endif diff --git a/src/nv_driver.c b/src/nv_driver.c index 9f6d75f..79c5c39 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -32,6 +32,10 @@ #ifdef DRI2 #include "dri2.h" #endif +#ifdef XORG_WAYLAND +#include <xf86Priv.h> +#include <xwayland.h> +#endif /* * Forward definitions for the functions that make up the driver. @@ -73,6 +77,28 @@ static Bool NVPciProbe ( DriverPtr drv, struct pci_device *dev, intptr_t match_data ); + +static Bool nouveau_driver_func(ScrnInfoPtr pScrn, + xorgDriverFuncOp op, + pointer ptr) +{ + xorgHWFlags *flag; + + switch (op) { + case GET_REQUIRED_HW_INTERFACES: + flag = (CARD32*)ptr; + (*flag) = 0; +#ifdef XORG_WAYLAND + if (xorgWayland) + (*flag) = HW_SKIP_CONSOLE; +#endif + return TRUE; + default: + /* Unknown or deprecated function */ + return FALSE; + } +} + /* * This contains the functions needed by the server after loading the * driver module. It must be supplied, and gets added the driver list by @@ -89,7 +115,7 @@ _X_EXPORT DriverRec NV = { NVAvailableOptions, NULL, 0, - NULL, + nouveau_driver_func, nouveau_device_match, NVPciProbe }; @@ -215,7 +241,28 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, drmVersion *version; int chipset, ret; char *busid; +#ifdef XORG_WAYLAND + struct xwl_screen *xwl_screen = NULL; + if (xorgWayland) { + xwl_screen = xwl_screen_create (); + if (!xwl_screen) { + xf86DrvMsg(-1, X_ERROR, "Failed to initialise xwayland.\n"); + return FALSE; + } + if (xwl_drm_pre_init(xwl_screen) != Success) { + xwl_screen_destroy(xwl_screen); + xf86DrvMsg(-1, X_ERROR, "Failed to initialise xwayland drm.\n"); + return FALSE; + } + ret = nouveau_device_wrap(xwl_screen_get_drm_fd(xwl_screen), 0, &dev); + if (ret) { + xwl_screen_destroy(xwl_screen); + xf86DrvMsg(-1, X_ERROR, "[drm] Failed to create drm device.\n"); + return FALSE; + } + } else { +#endif if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) { xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n"); return FALSE; @@ -229,6 +276,17 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, return FALSE; } + ret = drmCheckModesettingSupported(busid); + if (ret) { + xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); + return FALSE; + } + free(busid); + +#ifdef XORG_WAYLAND + } +#endif + /* Check the version reported by the kernel module. In theory we * shouldn't have to do this, as libdrm_nouveau will do its own checks. * But, we're currently using the kernel patchlevel to also version @@ -243,13 +301,6 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, chipset = dev->chipset; nouveau_device_del(&dev); - ret = drmCheckModesettingSupported(busid); - free(busid); - if (ret) { - xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); - return FALSE; - } - switch (chipset & 0xf0) { case 0x00: case 0x10: @@ -266,14 +317,21 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, case 0xe0: break; default: +#ifdef XORG_WAYLAND + xwl_screen_destroy(xwl_screen); +#endif xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset); return FALSE; } pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets, NULL, NULL, NULL, NULL, NULL); - if (!pScrn) + if (!pScrn) { +#ifdef XORG_WAYLAND + xwl_screen_destroy(xwl_screen); +#endif return FALSE; + } pScrn->driverVersion = NV_VERSION; pScrn->driverName = NV_DRIVER_NAME; @@ -288,6 +346,10 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device *pci_dev, pScrn->LeaveVT = NVLeaveVT; pScrn->FreeScreen = NVFreeScreen; +#ifdef XORG_WAYLAND + pScrn->driverPrivate = xwl_screen; +#endif + xf86SetEntitySharable(entity_num); pEnt = xf86GetEntityInfo(entity_num); @@ -376,6 +438,11 @@ NVFlushCallback(CallbackListPtr *list, pointer user_data, pointer call_data) if (pScrn->vtSema && !pNv->NoAccel) nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); +#ifdef XORG_WAYLAND + if (pNv->xwl_screen) + xwl_screen_post_damage(pNv->xwl_screen); +#endif + } static void @@ -399,6 +466,11 @@ NVBlockHandler ( if (pNv->VideoTimerCallback) (*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds); + +#ifdef XORG_WAYLAND + if (pNv->xwl_screen) + xwl_screen_post_damage(pNv->xwl_screen); +#endif } static Bool @@ -413,6 +485,11 @@ NVCreateScreenResources(ScreenPtr pScreen) return FALSE; pScreen->CreateScreenResources = NVCreateScreenResources; +#ifdef XORG_WAYLAND + if (pNv->xwl_screen) + xwl_screen_init(pNv->xwl_screen, pScreen); +#endif + drmmode_fbcon_copy(pScreen); if (!NVEnterVT(pScrn->scrnIndex, 0)) return FALSE; @@ -425,6 +502,27 @@ NVCreateScreenResources(ScreenPtr pScreen) return TRUE; } +#ifdef XORG_WAYLAND +static int nouveau_create_window_buffer(struct xwl_window *xwl_window, + PixmapPtr pixmap) +{ + uint32_t name; + struct nouveau_bo *bo; + + bo = nouveau_pixmap_bo(pixmap); + if (bo == NULL || nouveau_bo_name_get(bo, &name) != 0) + return BadDrawable; + + return xwl_create_window_buffer_drm(xwl_window, pixmap, name); +} + +static struct xwl_driver xwl_driver = { + .version = 1, + .use_drm = 1, + .create_window_buffer = nouveau_create_window_buffer +}; +#endif + /* * This is called at the end of each server generation. It restores the * original (text) mode. It should also unmap the video memory, and free @@ -439,6 +537,11 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; NVPtr pNv = NVPTR(pScrn); +#ifdef XORG_WAYLAND + if (pNv->xwl_screen) + xwl_screen_close(pNv->xwl_screen); +#endif + drmmode_screen_fini(pScreen); if (!pNv->NoAccel) @@ -507,6 +610,11 @@ NVFreeScreen(int scrnIndex, int flags) if (!pNv) return; +#ifdef XORG_WAYLAND + if (pNv->xwl_screen) + xwl_screen_destroy(pNv->xwl_screen); +#endif + NVCloseDRM(pScrn); free(pScrn->driverPrivate); @@ -568,10 +676,16 @@ NVPreInitDRM(ScrnInfoPtr pScrn) NVPtr pNv = NVPTR(pScrn); char *bus_id; int ret; + int drm_fd; if (!NVDRIGetVersion(pScrn)) return FALSE; +#ifdef XORG_WAYLAND + if (pNv->xwl_screen) + drm_fd = xwl_screen_get_drm_fd(pNv->xwl_screen); + else { +#endif /* Load the kernel module, and open the DRM */ bus_id = DRICreatePCIBusID(pNv->PciInfo); ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, bus_id, "nouveau"); @@ -582,8 +696,13 @@ NVPreInitDRM(ScrnInfoPtr pScrn) return FALSE; } + drm_fd = DRIMasterFD(pScrn); +#ifdef XORG_WAYLAND + } +#endif + /* Initialise libdrm_nouveau */ - ret = nouveau_device_wrap(DRIMasterFD(pScrn), 1, &pNv->dev); + ret = nouveau_device_wrap(drm_fd, 1, &pNv->dev); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] error creating device\n"); @@ -594,7 +713,7 @@ NVPreInitDRM(ScrnInfoPtr pScrn) if (ret) return FALSE; - pNv->drm_device_name = drmGetDeviceNameFromFd(DRIMasterFD(pScrn)); + pNv->drm_device_name = drmGetDeviceNameFromFd(drm_fd); return TRUE; } @@ -610,6 +729,9 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) uint64_t v; int ret; int defaultDepth = 0; +#ifdef XORG_WAYLAND + struct xwl_screen *xwl_screen = pScrn->driverPrivate; +#endif if (flags & PROBE_DETECT) { EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); @@ -643,6 +765,10 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) if (!(pScrn->driverPrivate = xnfcalloc(1, sizeof(NVRec)))) return FALSE; pNv = NVPTR(pScrn); + +#ifdef XORG_WAYLAND + pNv->xwl_screen = xwl_screen; +#endif /* Get the entity, and make sure it is PCI. */ pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); @@ -780,6 +906,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) memcpy(pNv->Options, NVOptions, sizeof(NVOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); +#ifdef XORG_WAYLAND + if (xwl_screen) { + if (!xwl_screen_pre_init(pScrn, xwl_screen, 0, &xwl_driver)) { + NVPreInitFail("Failed to initialise xwayland\n"); + } + } +#endif + from = X_DEFAULT; pNv->HWCursor = TRUE; @@ -887,8 +1021,8 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed %d]%s\n", pNv->swap_limit, pNv->max_swap_limit, reason); - ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3); - if (ret == FALSE) + if (!xwl_screen && + !drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3)) NVPreInitFail("Kernel modesetting failed to initialize\n"); /* @@ -1267,6 +1401,9 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); +#ifdef XORG_WAYLAND + if (!pNv->xwl_screen) +#endif drmmode_screen_init(pScreen); return TRUE; } diff --git a/src/nv_type.h b/src/nv_type.h index 49150ba..4e36b7f 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -15,6 +15,9 @@ #else #error "This driver requires a DRI-enabled X server" #endif +#ifdef XORG_WAYLAND +#include <xwayland.h> +#endif #define NV_ARCH_03 0x03 #define NV_ARCH_04 0x04 @@ -76,6 +79,10 @@ typedef struct _NVRec { void *drmmode; /* for KMS */ +#ifdef XORG_WAYLAND + struct xwl_screen *xwl_screen; +#endif + /* DRM interface */ struct nouveau_device *dev; char *drm_device_name; -- 1.7.10
On Wed, 23 May 2012 13:08:08 +0100, Christopher James Halse Rogers <christopher.halse.rogers at canonical.com> wrote:> Signed-off-by: Christopher James Halse Rogers > <christopher.halse.rogers at canonical.com> > --- > This is mostly just for testing, although it should be safe to apply to > nouveau > trunk.Hi Chris Thanks for the patch although it does not build on my system. Comments inline> > src/nouveau_dri2.c | 34 +++++++++++ > src/nv_driver.c | 163 > +++++++++++++++++++++++++++++++++++++++++++++++----- > src/nv_type.h | 7 +++ > 3 files changed, 191 insertions(+), 13 deletions(-) > > diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c > index 7e47575..cb1a395 100644 > --- a/src/nouveau_dri2.c > +++ b/src/nouveau_dri2.c > @@ -8,6 +8,10 @@ > #ifdef DRI2 > #include "dri2.h" > #endif > +#ifdef XORG_WAYLAND > +#include <xf86Priv.h> > +#include <xwayland.h> > +#endif > #if defined(DRI2) && DRI2INFOREC_VERSION >= 3 > struct nouveau_dri2_buffer { > @@ -660,6 +664,32 @@ nouveau_dri2_flip_event_handler(unsigned int frame, > unsigned int tv_sec, > free(flip); > } > +#ifdef XORG_WAYLAND > +static int nouveau_auth_magic(int fd, uint32_t magic) > +{ > + ScrnInfoPtr pScrn; > + NVPtr pNv; > + int i; > + > + /* Not wayland, go stragight to drm */ > + if (!xorgWayland) > + return drmAuthMagic(fd, magic); > + > + /* Technically this should actually iterate over xf86Screens. > + Since direct access to xf86Screens is going away, though, > + we don't bother right now */ > + for (i = 0; i < 1; i++) { > + pScrn = xf86Screens[i]; > + pNv = NVPTR(pScrn); > + if (xwl_screen_get_drm_fd(pNv->xwl_screen) == fd) > + break; > + } > + > + /* Forward the request to our host */ > + return xwl_drm_authenticate(pNv->xwl_screen, magic); > +} > +#endif > + > Bool > nouveau_dri2_init(ScreenPtr pScreen) > { > @@ -689,6 +719,10 @@ nouveau_dri2_init(ScreenPtr pScreen) > dri2.ScheduleWaitMSC = nouveau_dri2_schedule_wait; > dri2.GetMSC = nouveau_dri2_get_msc; > +#if DRI2INFOREC_VERSION >= 5 && defined(XORG_WAYLAND) > + dri2.AuthMagic = nouveau_auth_magic; > +#endif > + > #if DRI2INFOREC_VERSION >= 6 > dri2.SwapLimitValidate = nouveau_dri2_swap_limit_validate; > #endif > diff --git a/src/nv_driver.c b/src/nv_driver.c > index 9f6d75f..79c5c39 100644 > --- a/src/nv_driver.c > +++ b/src/nv_driver.c > @@ -32,6 +32,10 @@ > #ifdef DRI2 > #include "dri2.h" > #endif > +#ifdef XORG_WAYLAND > +#include <xf86Priv.h> > +#include <xwayland.h> > +#endif > /* > * Forward definitions for the functions that make up the driver. > @@ -73,6 +77,28 @@ static Bool NVPciProbe ( DriverPtr drv, > struct pci_device *dev, > intptr_t match_data ); > + > +static Bool nouveau_driver_func(ScrnInfoPtr pScrn, > + xorgDriverFuncOp op, > + pointer ptr) > +{ > + xorgHWFlags *flag; > + > + switch (op) { > + case GET_REQUIRED_HW_INTERFACES: > + flag = (CARD32*)ptr; > + (*flag) = 0; > +#ifdef XORG_WAYLAND > + if (xorgWayland) > + (*flag) = HW_SKIP_CONSOLE; > +#endif > + return TRUE; > + default: > + /* Unknown or deprecated function */ > + return FALSE; > + } > +} > + > /* > * This contains the functions needed by the server after loading the > * driver module. It must be supplied, and gets added the driver list > by > @@ -89,7 +115,7 @@ _X_EXPORT DriverRec NV = { > NVAvailableOptions, > NULL, > 0, > - NULL, > + nouveau_driver_func, > nouveau_device_match, > NVPciProbe > }; > @@ -215,7 +241,28 @@ NVPciProbe(DriverPtr drv, int entity_num, struct > pci_device *pci_dev, > drmVersion *version; > int chipset, ret; > char *busid; > +#ifdef XORG_WAYLAND > + struct xwl_screen *xwl_screen = NULL; > + if (xorgWayland) { > + xwl_screen = xwl_screen_create (); > + if (!xwl_screen) { > + xf86DrvMsg(-1, X_ERROR, "Failed to initialise xwayland.\n"); > + return FALSE; > + } > + if (xwl_drm_pre_init(xwl_screen) != Success) { > + xwl_screen_destroy(xwl_screen); > + xf86DrvMsg(-1, X_ERROR, "Failed to initialise xwayland drm.\n"); > + return FALSE; > + } > + ret = nouveau_device_wrap(xwl_screen_get_drm_fd(xwl_screen), 0, &dev); > + if (ret) { > + xwl_screen_destroy(xwl_screen); > + xf86DrvMsg(-1, X_ERROR, "[drm] Failed to create drm device.\n"); > + return FALSE; > + } > + } else { > +#endif > if (!xf86LoaderCheckSymbol("DRICreatePCIBusID")) { > xf86DrvMsg(-1, X_ERROR, "[drm] No DRICreatePCIBusID symbol\n"); > return FALSE; > @@ -229,6 +276,17 @@ NVPciProbe(DriverPtr drv, int entity_num, struct > pci_device *pci_dev, > return FALSE; > } > + ret = drmCheckModesettingSupported(busid); > + if (ret) { > + xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); > + return FALSE; > + } > + free(busid);Consider moving the free() before the conditional, or it will leak memory> + > +#ifdef XORG_WAYLAND > + } > +#endif > + > /* Check the version reported by the kernel module. In theory we > * shouldn't have to do this, as libdrm_nouveau will do its own checks. > * But, we're currently using the kernel patchlevel to also version > @@ -243,13 +301,6 @@ NVPciProbe(DriverPtr drv, int entity_num, struct > pci_device *pci_dev, > chipset = dev->chipset; > nouveau_device_del(&dev); > - ret = drmCheckModesettingSupported(busid); > - free(busid); > - if (ret) { > - xf86DrvMsg(-1, X_ERROR, "[drm] KMS not enabled\n"); > - return FALSE; > - } > - > switch (chipset & 0xf0) { > case 0x00: > case 0x10: > @@ -266,14 +317,21 @@ NVPciProbe(DriverPtr drv, int entity_num, struct > pci_device *pci_dev, > case 0xe0: > break; > default: > +#ifdef XORG_WAYLAND > + xwl_screen_destroy(xwl_screen); > +#endif > xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset); > return FALSE; > } > pScrn = xf86ConfigPciEntity(pScrn, 0, entity_num, NVChipsets, > NULL, NULL, NULL, NULL, NULL); > - if (!pScrn) > + if (!pScrn) { > +#ifdef XORG_WAYLAND > + xwl_screen_destroy(xwl_screen); > +#endif > return FALSE; > + } > pScrn->driverVersion = NV_VERSION; > pScrn->driverName = NV_DRIVER_NAME; > @@ -288,6 +346,10 @@ NVPciProbe(DriverPtr drv, int entity_num, struct > pci_device *pci_dev, > pScrn->LeaveVT = NVLeaveVT; > pScrn->FreeScreen = NVFreeScreen; > +#ifdef XORG_WAYLAND > + pScrn->driverPrivate = xwl_screen; > +#endif > + > xf86SetEntitySharable(entity_num); > pEnt = xf86GetEntityInfo(entity_num); > @@ -376,6 +438,11 @@ NVFlushCallback(CallbackListPtr *list, pointer > user_data, pointer call_data) > if (pScrn->vtSema && !pNv->NoAccel) > nouveau_pushbuf_kick(pNv->pushbuf, pNv->pushbuf->channel); > +#ifdef XORG_WAYLAND > + if (pNv->xwl_screen) > + xwl_screen_post_damage(pNv->xwl_screen); > +#endif > + > } > static void > @@ -399,6 +466,11 @@ NVBlockHandler ( > if (pNv->VideoTimerCallback) > (*pNv->VideoTimerCallback)(pScrn, currentTime.milliseconds); > + > +#ifdef XORG_WAYLAND > + if (pNv->xwl_screen) > + xwl_screen_post_damage(pNv->xwl_screen); > +#endif > } > static Bool > @@ -413,6 +485,11 @@ NVCreateScreenResources(ScreenPtr pScreen) > return FALSE; > pScreen->CreateScreenResources = NVCreateScreenResources; > +#ifdef XORG_WAYLAND > + if (pNv->xwl_screen) > + xwl_screen_init(pNv->xwl_screen, pScreen); > +#endif > + > drmmode_fbcon_copy(pScreen); > if (!NVEnterVT(pScrn->scrnIndex, 0)) > return FALSE; > @@ -425,6 +502,27 @@ NVCreateScreenResources(ScreenPtr pScreen) > return TRUE; > } > +#ifdef XORG_WAYLAND > +static int nouveau_create_window_buffer(struct xwl_window *xwl_window, > + PixmapPtr pixmap) > +{ > + uint32_t name; > + struct nouveau_bo *bo; > + > + bo = nouveau_pixmap_bo(pixmap); > + if (bo == NULL || nouveau_bo_name_get(bo, &name) != 0) > + return BadDrawable; > + > + return xwl_create_window_buffer_drm(xwl_window, pixmap, name); > +} > + > +static struct xwl_driver xwl_driver = { > + .version = 1, > + .use_drm = 1, > + .create_window_buffer = nouveau_create_window_buffer > +}; > +#endif > + > /* > * This is called at the end of each server generation. It restores the > * original (text) mode. It should also unmap the video memory, and > free > @@ -439,6 +537,11 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) > ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; > NVPtr pNv = NVPTR(pScrn); > +#ifdef XORG_WAYLAND > + if (pNv->xwl_screen) > + xwl_screen_close(pNv->xwl_screen); > +#endif > + > drmmode_screen_fini(pScreen); > if (!pNv->NoAccel) > @@ -507,6 +610,11 @@ NVFreeScreen(int scrnIndex, int flags) > if (!pNv) > return; > +#ifdef XORG_WAYLAND > + if (pNv->xwl_screen) > + xwl_screen_destroy(pNv->xwl_screen); > +#endif > + > NVCloseDRM(pScrn); > free(pScrn->driverPrivate); > @@ -568,10 +676,16 @@ NVPreInitDRM(ScrnInfoPtr pScrn) > NVPtr pNv = NVPTR(pScrn); > char *bus_id; > int ret; > + int drm_fd; > if (!NVDRIGetVersion(pScrn)) > return FALSE; > +#ifdef XORG_WAYLAND > + if (pNv->xwl_screen) > + drm_fd = xwl_screen_get_drm_fd(pNv->xwl_screen); > + else { > +#endif > /* Load the kernel module, and open the DRM */ > bus_id = DRICreatePCIBusID(pNv->PciInfo); > ret = DRIOpenDRMMaster(pScrn, SAREA_MAX, bus_id, "nouveau"); > @@ -582,8 +696,13 @@ NVPreInitDRM(ScrnInfoPtr pScrn) > return FALSE; > } > + drm_fd = DRIMasterFD(pScrn); > +#ifdef XORG_WAYLAND > + } > +#endif > + > /* Initialise libdrm_nouveau */ > - ret = nouveau_device_wrap(DRIMasterFD(pScrn), 1, &pNv->dev); > + ret = nouveau_device_wrap(drm_fd, 1, &pNv->dev); > if (ret) { > xf86DrvMsg(pScrn->scrnIndex, X_ERROR, > "[drm] error creating device\n"); > @@ -594,7 +713,7 @@ NVPreInitDRM(ScrnInfoPtr pScrn) > if (ret) > return FALSE; > - pNv->drm_device_name = drmGetDeviceNameFromFd(DRIMasterFD(pScrn)); > + pNv->drm_device_name = drmGetDeviceNameFromFd(drm_fd); > return TRUE; > } > @@ -610,6 +729,9 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) > uint64_t v; > int ret; > int defaultDepth = 0; > +#ifdef XORG_WAYLAND > + struct xwl_screen *xwl_screen = pScrn->driverPrivate; > +#endif > if (flags & PROBE_DETECT) { > EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); > @@ -643,6 +765,10 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) > if (!(pScrn->driverPrivate = xnfcalloc(1, sizeof(NVRec)))) > return FALSE; > pNv = NVPTR(pScrn); > + > +#ifdef XORG_WAYLAND > + pNv->xwl_screen = xwl_screen; > +#endif > /* Get the entity, and make sure it is PCI. */ > pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); > @@ -780,6 +906,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) > memcpy(pNv->Options, NVOptions, sizeof(NVOptions)); > xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); > +#ifdef XORG_WAYLAND > + if (xwl_screen) { > + if (!xwl_screen_pre_init(pScrn, xwl_screen, 0, &xwl_driver)) { > + NVPreInitFail("Failed to initialise xwayland\n"); > + } > + } > +#endif > + > from = X_DEFAULT; > pNv->HWCursor = TRUE; > @@ -887,8 +1021,8 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) > xf86DrvMsg(pScrn->scrnIndex, from, "Swap limit set to %d [Max allowed > %d]%s\n", > pNv->swap_limit, pNv->max_swap_limit, reason); > - ret = drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3); > - if (ret == FALSE) > + if (!xwl_screen &&xwl_screen is undefined on a non wayland build, resulting build failure Regards Emil> + !drmmode_pre_init(pScrn, pNv->dev->fd, pScrn->bitsPerPixel >> 3)) > NVPreInitFail("Kernel modesetting failed to initialize\n"); > /* > @@ -1267,6 +1401,9 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int > argc, char **argv) > if (serverGeneration == 1) > xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); > +#ifdef XORG_WAYLAND > + if (!pNv->xwl_screen) > +#endif > drmmode_screen_init(pScreen); > return TRUE; > } > diff --git a/src/nv_type.h b/src/nv_type.h > index 49150ba..4e36b7f 100644 > --- a/src/nv_type.h > +++ b/src/nv_type.h > @@ -15,6 +15,9 @@ > #else > #error "This driver requires a DRI-enabled X server" > #endif > +#ifdef XORG_WAYLAND > +#include <xwayland.h> > +#endif > #define NV_ARCH_03 0x03 > #define NV_ARCH_04 0x04 > @@ -76,6 +79,10 @@ typedef struct _NVRec { > void *drmmode; /* for KMS */ > +#ifdef XORG_WAYLAND > + struct xwl_screen *xwl_screen; > +#endif > + > /* DRM interface */ > struct nouveau_device *dev; > char *drm_device_name;