summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-10-20 19:37:50 -0700
committerKeith Packard <keithp@keithp.com>2017-10-20 19:37:50 -0700
commitb2c9a75f8bc647e31d1f24c5d76730e801e67607 (patch)
tree945e319517fb203a5e870f5c9775ed9ce1f39e11
parentf0d0d80dd0efee66c159ef7e8e7ca43c427c599d (diff)
Save changesdrm-lease-hacks
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--hw/xfree86/modes/xf86Crtc.h6
-rw-r--r--hw/xfree86/modes/xf86Cursors.c2
-rw-r--r--hw/xfree86/modes/xf86RandR12.c84
-rw-r--r--randr/randrstr.h10
-rw-r--r--randr/rrlease.c10
-rw-r--r--randr/rroutput.c27
-rw-r--r--randr/rrproperty.c31
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;