aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/randr
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/randr')
-rw-r--r--xorg-server/randr/randr.c96
-rw-r--r--xorg-server/randr/randrstr.h8
-rw-r--r--xorg-server/randr/rrcrtc.c4
-rw-r--r--xorg-server/randr/rroutput.c5
-rw-r--r--xorg-server/randr/rrprovider.c25
5 files changed, 138 insertions, 0 deletions
diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c
index cb6fce7cd..3c5142771 100644
--- a/xorg-server/randr/randr.c
+++ b/xorg-server/randr/randr.c
@@ -420,12 +420,40 @@ RRExtensionInit(void)
#endif
}
+void
+RRResourcesChanged(ScreenPtr pScreen)
+{
+ rrScrPriv(pScreen);
+ pScrPriv->resourcesChanged = TRUE;
+
+ RRSetChanged(pScreen);
+}
+
+static void
+RRDeliverResourceEvent(ClientPtr client, WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ xRRResourceChangeNotifyEvent re = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_ResourceChange,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id
+ };
+
+ WriteEventsToClient(client, 1, (xEvent *) &re);
+}
+
static int
TellChanged(WindowPtr pWin, pointer value)
{
RREventPtr *pHead, pRREvent;
ClientPtr client;
ScreenPtr pScreen = pWin->drawable.pScreen;
+ ScreenPtr iter;
+ rrScrPrivPtr pSlaveScrPriv;
rrScrPriv(pScreen);
int i;
@@ -450,6 +478,16 @@ TellChanged(WindowPtr pWin, pointer value)
if (crtc->changed)
RRDeliverCrtcEvent(client, pWin, crtc);
}
+
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++) {
+ RRCrtcPtr crtc = pSlaveScrPriv->crtcs[i];
+
+ if (crtc->changed)
+ RRDeliverCrtcEvent(client, pWin, crtc);
+ }
+ }
}
if (pRREvent->mask & RROutputChangeNotifyMask) {
@@ -459,6 +497,40 @@ TellChanged(WindowPtr pWin, pointer value)
if (output->changed)
RRDeliverOutputEvent(client, pWin, output);
}
+
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++) {
+ RROutputPtr output = pSlaveScrPriv->outputs[i];
+
+ if (output->changed)
+ RRDeliverOutputEvent(client, pWin, output);
+ }
+ }
+ }
+
+ if (pRREvent->mask & RRProviderChangeNotifyMask) {
+ xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->offload_slave_list, offload_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ xorg_list_for_each_entry(iter, &pScreen->unattached_list, unattached_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ if (pSlaveScrPriv->provider->changed)
+ RRDeliverProviderEvent(client, pWin, pSlaveScrPriv->provider);
+ }
+ }
+
+ if (pRREvent->mask & RRResourceChangeNotifyMask) {
+ if (pScrPriv->resourcesChanged) {
+ RRDeliverResourceEvent(client, pWin);
+ }
}
}
return WT_WALKCHILDREN;
@@ -496,6 +568,8 @@ RRTellChanged(ScreenPtr pScreen)
rrScrPriv(pScreen);
rrScrPrivPtr mastersp;
int i;
+ ScreenPtr iter;
+ rrScrPrivPtr pSlaveScrPriv;
if (pScreen->isGPU) {
master = pScreen->current_master;
@@ -514,11 +588,33 @@ RRTellChanged(ScreenPtr pScreen)
}
pScrPriv->changed = FALSE;
mastersp->changed = FALSE;
+
WalkTree(master, TellChanged, (pointer) master);
+
+ mastersp->resourcesChanged = FALSE;
+
for (i = 0; i < pScrPriv->numOutputs; i++)
pScrPriv->outputs[i]->changed = FALSE;
for (i = 0; i < pScrPriv->numCrtcs; i++)
pScrPriv->crtcs[i]->changed = FALSE;
+
+ xorg_list_for_each_entry(iter, &master->output_slave_list, output_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numOutputs; i++)
+ pSlaveScrPriv->outputs[i]->changed = FALSE;
+ for (i = 0; i < pSlaveScrPriv->numCrtcs; i++)
+ pSlaveScrPriv->crtcs[i]->changed = FALSE;
+ }
+ xorg_list_for_each_entry(iter, &master->offload_slave_list, offload_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ }
+ xorg_list_for_each_entry(iter, &master->unattached_list, unattached_head) {
+ pSlaveScrPriv = rrGetScrPriv(iter);
+ pSlaveScrPriv->provider->changed = FALSE;
+ }
+
if (mastersp->layoutChanged) {
pScrPriv->layoutChanged = FALSE;
RRPointerScreenConfigured(master);
diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h
index 2babfedd2..15299fd6d 100644
--- a/xorg-server/randr/randrstr.h
+++ b/xorg-server/randr/randrstr.h
@@ -164,6 +164,7 @@ struct _rrProvider {
int nameLength;
RRPropertyPtr properties;
Bool pendingProperties;
+ Bool changed;
struct _rrProvider *offload_sink;
struct _rrProvider *output_source;
};
@@ -300,6 +301,7 @@ typedef struct _rrScrPriv {
Bool changed; /* some config changed */
Bool configChanged; /* configuration changed */
Bool layoutChanged; /* screen layout changed */
+ Bool resourcesChanged; /* screen resources change */
CARD16 minWidth, minHeight;
CARD16 maxWidth, maxHeight;
@@ -485,6 +487,9 @@ extern _X_EXPORT int
extern _X_EXPORT void
RRDeliverScreenEvent(ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
+extern _X_EXPORT void
+ RRResourcesChanged(ScreenPtr pScreen);
+
/* randr.c */
/* set a screen change on the primary screen */
extern _X_EXPORT void
@@ -923,6 +928,9 @@ RRProviderSetCapabilities(RRProviderPtr provider, uint32_t capabilities);
extern _X_EXPORT Bool
RRProviderLookup(XID id, RRProviderPtr *provider_p);
+extern _X_EXPORT void
+RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider);
+
/* rrproviderproperty.c */
extern _X_EXPORT void
diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c
index 2f76b62be..99b3dca08 100644
--- a/xorg-server/randr/rrcrtc.c
+++ b/xorg-server/randr/rrcrtc.c
@@ -102,6 +102,8 @@ RRCrtcCreate(ScreenPtr pScreen, void *devPrivate)
crtc->pScreen = pScreen;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
+ RRResourcesChanged(pScreen);
+
return crtc;
}
@@ -669,6 +671,8 @@ RRCrtcDestroyResource(pointer value, XID pid)
break;
}
}
+
+ RRResourcesChanged(pScreen);
}
if (crtc->scanout_pixmap)
diff --git a/xorg-server/randr/rroutput.c b/xorg-server/randr/rroutput.c
index 922d61f3d..2b0b82f4c 100644
--- a/xorg-server/randr/rroutput.c
+++ b/xorg-server/randr/rroutput.c
@@ -101,6 +101,9 @@ RROutputCreate(ScreenPtr pScreen,
return NULL;
pScrPriv->outputs[pScrPriv->numOutputs++] = output;
+
+ RRResourcesChanged(pScreen);
+
return output;
}
@@ -355,6 +358,8 @@ RROutputDestroyResource(pointer value, XID pid)
break;
}
}
+
+ RRResourcesChanged(pScreen);
}
if (output->modes) {
for (m = 0; m < output->numModes; m++)
diff --git a/xorg-server/randr/rrprovider.c b/xorg-server/randr/rrprovider.c
index b321e6227..2334ad277 100644
--- a/xorg-server/randr/rrprovider.c
+++ b/xorg-server/randr/rrprovider.c
@@ -304,6 +304,9 @@ ProcRRSetProviderOutputSource(ClientPtr client)
pScrPriv->rrProviderSetOutputSource(pScreen, provider, source_provider);
+ provider->changed = TRUE;
+ RRSetChanged(pScreen);
+
RRTellChanged (pScreen);
return Success;
@@ -333,6 +336,9 @@ ProcRRSetProviderOffloadSink(ClientPtr client)
pScrPriv->rrProviderSetOffloadSink(pScreen, provider, sink_provider);
+ provider->changed = TRUE;
+ RRSetChanged(pScreen);
+
RRTellChanged (pScreen);
return Success;
@@ -357,6 +363,7 @@ RRProviderCreate(ScreenPtr pScreen, const char *name,
provider->nameLength = nameLength;
memcpy(provider->name, name, nameLength);
provider->name[nameLength] = '\0';
+ provider->changed = FALSE;
if (!AddResource (provider->id, RRProviderType, (pointer) provider))
return NULL;
@@ -416,3 +423,21 @@ RRProviderLookup(XID id, RRProviderPtr *provider_p)
return TRUE;
return FALSE;
}
+
+void
+RRDeliverProviderEvent(ClientPtr client, WindowPtr pWin, RRProviderPtr provider)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ rrScrPriv(pScreen);
+
+ xRRProviderChangeNotifyEvent pe = {
+ .type = RRNotify + RREventBase,
+ .subCode = RRNotify_ProviderChange,
+ .timestamp = pScrPriv->lastSetTime.milliseconds,
+ .window = pWin->drawable.id,
+ .provider = provider->id
+ };
+
+ WriteEventsToClient(client, 1, (xEvent *) &pe);
+}