diff options
Diffstat (limited to 'xorg-server/randr')
-rw-r--r-- | xorg-server/randr/randr.c | 96 | ||||
-rw-r--r-- | xorg-server/randr/randrstr.h | 8 | ||||
-rw-r--r-- | xorg-server/randr/rrcrtc.c | 4 | ||||
-rw-r--r-- | xorg-server/randr/rroutput.c | 5 | ||||
-rw-r--r-- | xorg-server/randr/rrprovider.c | 25 |
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); +} |