randr: Support "non-desktop" property

Tracks changes to the non-desktop property so that when non-zero,
outputs will always appear to be disconnected.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@nwnk.net>
This commit is contained in:
Keith Packard 2018-02-12 13:51:54 -08:00 committed by Adam Jackson
parent b91c787c4c
commit 3957360505
3 changed files with 55 additions and 1 deletions

View File

@ -153,6 +153,7 @@ struct _rrOutput {
int numUserModes;
RRModePtr *userModes;
Bool changed;
Bool nonDesktop;
RRPropertyPtr properties;
Bool pendingProperties;
void *devPrivate;
@ -551,6 +552,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);

View File

@ -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;
@ -111,6 +113,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;
@ -311,6 +320,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);
uint32_t value = nonDesktop ? 1 : 0;
if (nonDesktopProp == None || nonDesktopProp == BAD_RESOURCE)
return FALSE;
return RRChangeOutputProperty(output, nonDesktopProp, XA_INTEGER, 32,
PropModeReplace, 1, &value, TRUE, FALSE) == Success;
}
void
RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output)
{
@ -330,7 +353,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);
@ -442,6 +465,7 @@ ProcRRGetOutputInfo(ClientPtr client)
.crtc = output->crtc ? output->crtc->id : None,
.mmWidth = output->mmWidth,
.mmHeight = output->mmHeight,
.connection = output->nonDesktop ? RR_Disconnected : output->connection,
.connection = output->connection,
.subpixelOrder = output->subpixelOrder,
.nCrtcs = output->numCrtcs,

View File

@ -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,6 +133,29 @@ 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 == 32 && value->size >= 1) {
uint32_t nonDesktopData;
Bool nonDesktop;
memcpy(&nonDesktopData, value->data, sizeof (nonDesktopData));
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,
@ -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,