Blob Blame History Raw
From 3e664963b630597e8ffefca235afe2bbd6050253 Mon Sep 17 00:00:00 2001
From: Michal Srb <msrb@suse.com>
Date: Wed, 30 Oct 2013 13:33:49 +0200
Subject: [PATCH] randr: send RRProviderChangeNotify event

Send RRProviderChangeNotify event when a provider becomes output source or
offload sink.

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Michal Srb <msrb@suse.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
---
 randr/randr.c      | 36 ++++++++++++++++++++++++++++++++++++
 randr/randrstr.h   |  4 ++++
 randr/rrprovider.c | 25 +++++++++++++++++++++++++
 3 files changed, 65 insertions(+)

diff --git a/randr/randr.c b/randr/randr.c
index cb6fce7..fa0a4da 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -426,6 +426,8 @@ TellChanged(WindowPtr pWin, pointer value)
     RREventPtr *pHead, pRREvent;
     ClientPtr client;
     ScreenPtr pScreen = pWin->drawable.pScreen;
+    ScreenPtr iter;
+    rrScrPrivPtr pSlaveScrPriv;
 
     rrScrPriv(pScreen);
     int i;
@@ -460,6 +462,24 @@ TellChanged(WindowPtr pWin, pointer value)
                     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);
+            }
+        }
     }
     return WT_WALKCHILDREN;
 }
@@ -496,6 +516,8 @@ RRTellChanged(ScreenPtr pScreen)
     rrScrPriv(pScreen);
     rrScrPrivPtr mastersp;
     int i;
+    ScreenPtr iter;
+    rrScrPrivPtr pSlaveScrPriv;
 
     if (pScreen->isGPU) {
         master = pScreen->current_master;
@@ -519,6 +541,20 @@ RRTellChanged(ScreenPtr pScreen)
             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;
+        }
+        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/randr/randrstr.h b/randr/randrstr.h
index 2babfed..3427378 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -166,6 +166,7 @@ struct _rrProvider {
     Bool pendingProperties;
     struct _rrProvider *offload_sink;
     struct _rrProvider *output_source;
+    Bool changed;
 };
 
 #if RANDR_12_INTERFACE
@@ -923,6 +924,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/randr/rrprovider.c b/randr/rrprovider.c
index b321e62..2334ad2 100644
--- a/randr/rrprovider.c
+++ b/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);
+}
-- 
1.8.3.1