6c7b302
From 9cd3cc75269d9196898487b5712ee47b8291e077 Mon Sep 17 00:00:00 2001
6c7b302
From: Hans De Goede <hdegoede@redhat.com>
6c7b302
Date: Mon, 12 Dec 2016 17:03:14 +0100
6c7b302
Subject: [PATCH xserver 3/6] xfree86: Add options support for OutputClass
6c7b302
 Options
6c7b302
6c7b302
Add support for setting options in OutputClass Sections and having these
6c7b302
applied to any matching output devices.
6c7b302
6c7b302
Reviewed-by: Adam Jackson <ajax@redhat.com>
6c7b302
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
6c7b302
---
6c7b302
 hw/xfree86/common/xf86Option.c      |  5 ++++-
6c7b302
 hw/xfree86/common/xf86platformBus.c | 42 +++++++++++++++++++++++++++++++++++++
6c7b302
 hw/xfree86/common/xf86platformBus.h |  2 ++
6c7b302
 hw/xfree86/man/xorg.conf.man        | 10 +++++++++
6c7b302
 hw/xfree86/parser/OutputClass.c     |  6 ++++++
6c7b302
 hw/xfree86/parser/xf86Parser.h      |  1 +
6c7b302
 6 files changed, 65 insertions(+), 1 deletion(-)
6c7b302
6c7b302
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
6c7b302
index 0e8bc1f..929724d 100644
6c7b302
--- a/hw/xfree86/common/xf86Option.c
6c7b302
+++ b/hw/xfree86/common/xf86Option.c
6c7b302
@@ -44,6 +44,7 @@
6c7b302
 #include "xf86Xinput.h"
6c7b302
 #include "xf86Optrec.h"
6c7b302
 #include "xf86Parser.h"
6c7b302
+#include "xf86platformBus.h" /* For OutputClass functions */
6c7b302
 #include "optionstr.h"
6c7b302
 
6c7b302
 static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options,
6c7b302
@@ -64,7 +65,7 @@ static Bool ParseOptionValue(int scrnIndex, XF86OptionPtr options,
6c7b302
  *
6c7b302
  * The order of precedence for options is:
6c7b302
  *
6c7b302
- *   extraOpts, display, confScreen, monitor, device
6c7b302
+ *   extraOpts, display, confScreen, monitor, device, outputClassOptions
6c7b302
  */
6c7b302
 
6c7b302
 void
6c7b302
@@ -79,6 +80,8 @@ xf86CollectOptions(ScrnInfoPtr pScrn, XF86OptionPtr extraOpts)
6c7b302
     pScrn->options = NULL;
6c7b302
 
6c7b302
     for (i = pScrn->numEntities - 1; i >= 0; i--) {
6c7b302
+        xf86MergeOutputClassOptions(pScrn->entityList[i], &pScrn->options);
6c7b302
+
6c7b302
         device = xf86GetDevFromEntity(pScrn->entityList[i],
6c7b302
                                       pScrn->entityInstanceList[i]);
6c7b302
         if (device && device->options) {
6c7b302
diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c
6c7b302
index 25a9040..a698c6c 100644
6c7b302
--- a/hw/xfree86/common/xf86platformBus.c
6c7b302
+++ b/hw/xfree86/common/xf86platformBus.c
6c7b302
@@ -310,6 +310,48 @@ xf86platformProbe(void)
6c7b302
     return 0;
6c7b302
 }
6c7b302
 
6c7b302
+void
6c7b302
+xf86MergeOutputClassOptions(int entityIndex, void **options)
6c7b302
+{
6c7b302
+    const EntityPtr entity = xf86Entities[entityIndex];
6c7b302
+    struct xf86_platform_device *dev = NULL;
6c7b302
+    XF86ConfOutputClassPtr cl;
6c7b302
+    XF86OptionPtr classopts;
6c7b302
+    int i = 0;
6c7b302
+
6c7b302
+    switch (entity->bus.type) {
6c7b302
+    case BUS_PLATFORM:
6c7b302
+        dev = entity->bus.id.plat;
6c7b302
+        break;
6c7b302
+    case BUS_PCI:
6c7b302
+        for (i = 0; i < xf86_num_platform_devices; i++) {
6c7b302
+            if (MATCH_PCI_DEVICES(xf86_platform_devices[i].pdev,
6c7b302
+                                  entity->bus.id.pci)) {
6c7b302
+                dev = &xf86_platform_devices[i];
6c7b302
+                break;
6c7b302
+            }
6c7b302
+        }
6c7b302
+        break;
6c7b302
+    default:
6c7b302
+        xf86Msg(X_DEBUG, "xf86MergeOutputClassOptions unsupported bus type %d\n",
6c7b302
+                entity->bus.type);
6c7b302
+    }
6c7b302
+
6c7b302
+    if (!dev)
6c7b302
+        return;
6c7b302
+
6c7b302
+    for (cl = xf86configptr->conf_outputclass_lst; cl; cl = cl->list.next) {
6c7b302
+        if (!OutputClassMatches(cl, dev) || !cl->option_lst)
6c7b302
+            continue;
6c7b302
+
6c7b302
+        xf86Msg(X_INFO, "Applying OutputClass \"%s\" options to %s\n",
6c7b302
+                cl->identifier, dev->attribs->path);
6c7b302
+
6c7b302
+        classopts = xf86optionListDup(cl->option_lst);
6c7b302
+        *options = xf86optionListMerge(*options, classopts);
6c7b302
+    }
6c7b302
+}
6c7b302
+
6c7b302
 static int
6c7b302
 xf86ClaimPlatformSlot(struct xf86_platform_device * d, DriverPtr drvp,
6c7b302
                   int chipset, GDevPtr dev, Bool active)
6c7b302
diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h
6c7b302
index 0f5c0ef..70d9ec8 100644
6c7b302
--- a/hw/xfree86/common/xf86platformBus.h
6c7b302
+++ b/hw/xfree86/common/xf86platformBus.h
6c7b302
@@ -42,6 +42,7 @@ struct xf86_platform_device {
6c7b302
 int xf86platformProbe(void);
6c7b302
 int xf86platformProbeDev(DriverPtr drvp);
6c7b302
 int xf86platformAddGPUDevices(DriverPtr drvp);
6c7b302
+void xf86MergeOutputClassOptions(int entityIndex, void **options);
6c7b302
 
6c7b302
 extern int xf86_num_platform_devices;
6c7b302
 extern struct xf86_platform_device *xf86_platform_devices;
6c7b302
@@ -161,6 +162,7 @@ extern void xf86platformPrimary(void);
6c7b302
 #else
6c7b302
 
6c7b302
 static inline int xf86platformAddGPUDevices(DriverPtr drvp) { return FALSE; }
6c7b302
+static inline void xf86MergeOutputClassOptions(int index, void **options) {}
6c7b302
 
6c7b302
 #endif
6c7b302
 
6c7b302
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
6c7b302
index 7d0c524..8928a53 100644
6c7b302
--- a/hw/xfree86/man/xorg.conf.man
6c7b302
+++ b/hw/xfree86/man/xorg.conf.man
6c7b302
@@ -1280,6 +1280,16 @@ For example:
6c7b302
 Check the case-sensitive string
6c7b302
 .RI \*q matchdriver \*q
6c7b302
 against the kernel driver of the device.
6c7b302
+.PP
6c7b302
+When an output device has been matched to the
6c7b302
+.B OutputClass
6c7b302
+section, any
6c7b302
+.B Option
6c7b302
+entries are applied to the device. See the
6c7b302
+.B Device
6c7b302
+section below for a description of the remaining
6c7b302
+.B Option
6c7b302
+entries.
6c7b302
 .SH "DEVICE SECTION"
6c7b302
 The config file may have multiple
6c7b302
 .B Device
6c7b302
diff --git a/hw/xfree86/parser/OutputClass.c b/hw/xfree86/parser/OutputClass.c
6c7b302
index 8064e0c..f813ee6 100644
6c7b302
--- a/hw/xfree86/parser/OutputClass.c
6c7b302
+++ b/hw/xfree86/parser/OutputClass.c
6c7b302
@@ -36,6 +36,7 @@ static const xf86ConfigSymTabRec OutputClassTab[] = {
6c7b302
     {ENDSECTION, "endsection"},
6c7b302
     {IDENTIFIER, "identifier"},
6c7b302
     {DRIVER, "driver"},
6c7b302
+    {OPTION, "option"},
6c7b302
     {MATCH_DRIVER, "matchdriver"},
6c7b302
     {-1, ""},
6c7b302
 };
6c7b302
@@ -60,6 +61,8 @@ xf86freeOutputClassList(XF86ConfOutputClassPtr ptr)
6c7b302
             free(group);
6c7b302
         }
6c7b302
 
6c7b302
+        xf86optionListFree(ptr->option_lst);
6c7b302
+
6c7b302
         prev = ptr;
6c7b302
         ptr = ptr->list.next;
6c7b302
         free(prev);
6c7b302
@@ -112,6 +115,9 @@ xf86parseOutputClassSection(void)
6c7b302
             else
6c7b302
                 ptr->driver = xf86_lex_val.str;
6c7b302
             break;
6c7b302
+        case OPTION:
6c7b302
+            ptr->option_lst = xf86parseOption(ptr->option_lst);
6c7b302
+            break;
6c7b302
         case MATCH_DRIVER:
6c7b302
             if (xf86getSubToken(&(ptr->comment)) != STRING)
6c7b302
                 Error(QUOTE_MSG, "MatchDriver");
6c7b302
diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
6c7b302
index 9c4b403..897edab 100644
6c7b302
--- a/hw/xfree86/parser/xf86Parser.h
6c7b302
+++ b/hw/xfree86/parser/xf86Parser.h
6c7b302
@@ -338,6 +338,7 @@ typedef struct {
6c7b302
     char *identifier;
6c7b302
     char *driver;
6c7b302
     struct xorg_list match_driver;
6c7b302
+    XF86OptionPtr option_lst;
6c7b302
     char *comment;
6c7b302
 } XF86ConfOutputClassRec, *XF86ConfOutputClassPtr;
6c7b302
 
6c7b302
-- 
6c7b302
2.9.3
6c7b302