diff options
author | Keith Packard <keithp@keithp.com> | 2017-10-20 19:37:50 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2017-10-20 19:37:50 -0700 |
commit | b2c9a75f8bc647e31d1f24c5d76730e801e67607 (patch) | |
tree | 945e319517fb203a5e870f5c9775ed9ce1f39e11 | |
parent | f0d0d80dd0efee66c159ef7e8e7ca43c427c599d (diff) |
Save changesdrm-lease-hacks
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.h | 6 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Cursors.c | 2 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86RandR12.c | 84 | ||||
-rw-r--r-- | randr/randrstr.h | 10 | ||||
-rw-r--r-- | randr/rrlease.c | 10 | ||||
-rw-r--r-- | randr/rroutput.c | 27 | ||||
-rw-r--r-- | randr/rrproperty.c | 31 |
7 files changed, 151 insertions, 19 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index e3aaf1af6..470e11339 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -1075,6 +1075,12 @@ extern _X_EXPORT void xf86_crtc_hide_cursor(xf86CrtcPtr crtc); /** + * Called by the driver to turn a single crtc's cursor on + */ +extern _X_EXPORT Bool +xf86_crtc_show_cursor(xf86CrtcPtr crtc); + +/** * Called by the driver to turn cursors off */ extern _X_EXPORT void diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index ae2137d80..231ab8ac6 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -344,7 +344,7 @@ xf86_hide_cursors(ScrnInfoPtr scrn) } } -static Bool +Bool xf86_crtc_show_cursor(xf86CrtcPtr crtc) { if (!crtc->cursor_in_range) diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 6c6970952..d3e535788 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -2163,11 +2163,29 @@ xf86RandR14ProviderDestroy(ScreenPtr screen, RRProviderPtr provider) config->randr_provider = NULL; } +static void +xf86CrtcCheckReset(xf86CrtcPtr crtc) { + if (xf86CrtcInUse(crtc)) { + RRTransformPtr transform; + + if (crtc->desiredTransformPresent) + transform = &crtc->desiredTransform; + else + transform = NULL; + xf86CrtcSetModeTransform(crtc, &crtc->desiredMode, + crtc->desiredRotation, transform, + crtc->desiredX, crtc->desiredY); + xf86_crtc_show_cursor(crtc); + } +} + void xf86CrtcLeaseTerminated(RRLeasePtr lease) { int c; + int o; + RRLeaseTerminated(lease); /* * Force a full mode set on any crtc in the expiring lease which * was running before the lease started @@ -2176,32 +2194,74 @@ xf86CrtcLeaseTerminated(RRLeasePtr lease) RRCrtcPtr randr_crtc = lease->crtcs[c]; xf86CrtcPtr crtc = randr_crtc->devPrivate; - crtc->enabled = xf86CrtcInUse(crtc); - if (crtc->enabled) { - RRTransformPtr transform; + xf86CrtcCheckReset(crtc); + } - if (crtc->desiredTransformPresent) - transform = &crtc->desiredTransform; - else - transform = NULL; - xf86CrtcSetModeTransform(crtc, &crtc->desiredMode, - crtc->desiredRotation, transform, - crtc->desiredX, crtc->desiredY); + /* Check to see if any leased output is using a crtc which + * was not reset in the above loop + */ + for (o = 0; o < lease->numOutputs; o++) { + RROutputPtr randr_output = lease->outputs[o]; + xf86OutputPtr output = randr_output->devPrivate; + xf86CrtcPtr crtc = output->crtc; + + if (crtc) { + for (c = 0; c < lease->numCrtcs; c++) + if (lease->crtcs[c] == crtc->randr_crtc) + break; + if (c != lease->numCrtcs) + continue; + xf86CrtcCheckReset(crtc); } } - RRLeaseTerminated(lease); + RRLeaseFree(lease); +} + +static Bool +xf86CrtcSoleOutput(xf86CrtcPtr crtc, xf86OutputPtr output) +{ + ScrnInfoPtr scrn = crtc->scrn; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr other = config->output[o]; + + if (other != output && other->crtc == crtc) + return FALSE; + } + return TRUE; } void xf86CrtcLeaseStarted(RRLeasePtr lease) { int c; + int o; for (c = 0; c < lease->numCrtcs; c++) { RRCrtcPtr randr_crtc = lease->crtcs[c]; xf86CrtcPtr crtc = randr_crtc->devPrivate; - crtc->enabled = FALSE; + if (crtc->enabled) { + /* + * Leave the primary plane enabled so we can + * flip without blanking the screen. Hide + * the cursor so it doesn't remain on the screen + * while the lease is active + */ + xf86_crtc_hide_cursor(crtc); + crtc->enabled = FALSE; + } + } + for (o = 0; o < lease->numOutputs; o++) { + RROutputPtr randr_output = lease->outputs[o]; + xf86OutputPtr output = randr_output->devPrivate; + xf86CrtcPtr crtc = output->crtc; + + if (crtc) + if (xf86CrtcSoleOutput(crtc, output)) + crtc->enabled = FALSE; } } diff --git a/randr/randrstr.h b/randr/randrstr.h index 0d7e91b0e..b01d4a000 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -155,6 +155,7 @@ struct _rrOutput { int numUserModes; RRModePtr *userModes; Bool changed; + Bool nonDesktop; RRPropertyPtr properties; Bool pendingProperties; void *devPrivate; @@ -592,6 +593,8 @@ extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen); extern _X_EXPORT RROutputPtr RRFirstOutput(ScreenPtr pScreen); +extern _X_EXPORT Bool RROutputSetNonDesktop(RROutputPtr output, Bool non_desktop); + extern _X_EXPORT CARD16 RRVerticalRefresh(xRRModeInfo * mode); @@ -817,6 +820,9 @@ RRDeliverLeaseEvent(ClientPtr client, WindowPtr window); void RRLeaseTerminated(RRLeasePtr lease); +void +RRLeaseFree(RRLeasePtr lease); + extern _X_EXPORT Bool RRCrtcIsLeased(RRCrtcPtr crtc); @@ -972,13 +978,13 @@ extern _X_EXPORT int RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, int format, int mode, unsigned long len, - void *value, Bool sendevent, Bool pending); + const void *value, Bool sendevent, Bool pending); extern _X_EXPORT int RRConfigureOutputProperty(RROutputPtr output, Atom property, Bool pending, Bool range, Bool immutable, - int num_values, INT32 *values); + int num_values, const INT32 *values); extern _X_EXPORT int ProcRRChangeOutputProperty(ClientPtr client); diff --git a/randr/rrlease.c b/randr/rrlease.c index 605250b8d..b4a8827cc 100644 --- a/randr/rrlease.c +++ b/randr/rrlease.c @@ -138,6 +138,7 @@ RROutputIsLeased(RROutputPtr output) * The driver is responsible for noticing and * calling this function when that happens */ + void RRLeaseTerminated(RRLeasePtr lease) { @@ -149,7 +150,16 @@ RRLeaseTerminated(RRLeasePtr lease) FreeResource(lease->id, RT_NONE); xorg_list_del(&lease->list); +} +/* + * A lease is completely shut down and is + * ready to be deallocated + */ + +void +RRLeaseFree(RRLeasePtr lease) +{ free(lease); } diff --git a/randr/rroutput.c b/randr/rroutput.c index cb7306649..a7784885c 100644 --- a/randr/rroutput.c +++ b/randr/rroutput.c @@ -22,6 +22,7 @@ */ #include "randrstr.h" +#include <X11/Xatom.h> RESTYPE RROutputType; @@ -65,6 +66,7 @@ RROutputCreate(ScreenPtr pScreen, RROutputPtr output; RROutputPtr *outputs; rrScrPrivPtr pScrPriv; + Atom nonDesktopAtom; if (!RRInit()) return NULL; @@ -114,6 +116,13 @@ RROutputCreate(ScreenPtr pScreen, pScrPriv->outputs[pScrPriv->numOutputs++] = output; + nonDesktopAtom = MakeAtom(RR_PROPERTY_NON_DESKTOP, strlen(RR_PROPERTY_NON_DESKTOP), TRUE); + if (nonDesktopAtom != BAD_RESOURCE) { + static const INT32 values[2] = { 0, 1 }; + (void) RRConfigureOutputProperty(output, nonDesktopAtom, FALSE, FALSE, FALSE, + 2, values); + } + RROutputSetNonDesktop(output, FALSE); RRResourcesChanged(pScreen); return output; @@ -314,6 +323,20 @@ RROutputSetPhysicalSize(RROutputPtr output, int mmWidth, int mmHeight) return TRUE; } +Bool +RROutputSetNonDesktop(RROutputPtr output, Bool nonDesktop) +{ + const char *nonDesktopStr = RR_PROPERTY_NON_DESKTOP; + Atom nonDesktopProp = MakeAtom(nonDesktopStr, strlen(nonDesktopStr), TRUE); + uint8_t value = nonDesktop ? 1 : 0; + + if (nonDesktopProp == None || nonDesktopProp == BAD_RESOURCE) + return FALSE; + + return RRChangeOutputProperty(output, nonDesktopProp, XA_INTEGER, 8, + PropModeReplace, 1, &value, TRUE, FALSE) == Success; +} + void RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) { @@ -333,7 +356,7 @@ RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output) .crtc = crtc ? crtc->id : None, .mode = mode ? mode->mode.id : None, .rotation = crtc ? crtc->rotation : RR_Rotate_0, - .connection = output->connection, + .connection = output->nonDesktop ? RR_Disconnected : output->connection, .subpixelOrder = output->subpixelOrder }; WriteEventsToClient(client, 1, (xEvent *) &oe); @@ -478,7 +501,7 @@ ProcRRGetOutputInfo(ClientPtr client) .crtc = output->crtc ? output->crtc->id : None, .mmWidth = output->mmWidth, .mmHeight = output->mmHeight, - .connection = output->connection, + .connection = output->nonDesktop ? RR_Disconnected : output->connection, .subpixelOrder = output->subpixelOrder, .nCrtcs = output->numCrtcs, .nModes = output->numModes + output->numUserModes, diff --git a/randr/rrproperty.c b/randr/rrproperty.c index b5a591de5..0e6cdf50a 100644 --- a/randr/rrproperty.c +++ b/randr/rrproperty.c @@ -23,6 +23,7 @@ #include "randrstr.h" #include "propertyst.h" #include "swaprep.h" +#include <X11/Xatom.h> static int DeliverPropertyEvent(WindowPtr pWin, void *value) @@ -132,10 +133,33 @@ RRDeleteOutputProperty(RROutputPtr output, Atom property) } } +static void +RRNoticePropertyChange(RROutputPtr output, Atom property, RRPropertyValuePtr value) +{ + const char *non_desktop_str = RR_PROPERTY_NON_DESKTOP; + Atom non_desktop_prop = MakeAtom(non_desktop_str, strlen(non_desktop_str), FALSE); + + if (property == non_desktop_prop) { + if (value->type == XA_INTEGER && value->format == 8 && value->size >= 1) { + uint8_t nonDesktopData; + Bool nonDesktop + + memcpy(&nonDesktopData, value->data, 1); + nonDesktop = nonDesktopData != 0; + + if (nonDesktop != output->nonDesktop) { + output->nonDesktop = nonDesktop; + RROutputChanged(output, 0); + RRTellChanged(output->pScreen); + } + } + } +} + int RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, int format, int mode, unsigned long len, - void *value, Bool sendevent, Bool pending) + const void *value, Bool sendevent, Bool pending) { RRPropertyPtr prop; rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen); @@ -235,6 +259,9 @@ RRChangeOutputProperty(RROutputPtr output, Atom property, Atom type, if (pending && prop->is_pending) output->pendingProperties = TRUE; + if (!(pending && prop->is_pending)) + RRNoticePropertyChange(output, prop->propertyName, prop_value); + if (sendevent) { xRROutputPropertyNotifyEvent event = { .type = RREventBase + RRNotify, @@ -324,7 +351,7 @@ RRGetOutputProperty(RROutputPtr output, Atom property, Bool pending) int RRConfigureOutputProperty(RROutputPtr output, Atom property, Bool pending, Bool range, Bool immutable, - int num_values, INT32 *values) + int num_values, const INT32 *values) { RRPropertyPtr prop = RRQueryOutputProperty(output, property); Bool add = FALSE; |