[RFC 2/3] xfree86: Introduce OutputClass configuration
Aaron Plattner
aplattner at nvidia.com
Thu Feb 13 08:50:35 PST 2014
On 02/13/14 05:22, Thierry Reding wrote:
> The OutputClass section provides a way to match output devices to a set
> of given attributes and configure them. For now, only matching by kernel
> driver name is supported. This can be used to determine what DDX module
> to load for non-PCI output devices. DDX modules can ship an xorg.conf.d
> snippet (e.g. in /usr/share/X11/xorg.conf.d) that looks like this:
>
> Section "OutputClass"
> Identifer "NVIDIA Tegra open-source driver"
> MatchDriver "tegra"
> Driver "opentegra"
> EndSection
>
> This will cause any device that's driven by the kernel driver named
> "tegra" to use the "opentegra" DDX module.
>
> See the OUTPUTCLASS section in xorg.conf(5) for more details.
>
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
> hw/xfree86/man/xorg.conf.man | 74 ++++++++++++++++++
> hw/xfree86/parser/Makefile.am | 1 +
> hw/xfree86/parser/OutputClass.c | 167 ++++++++++++++++++++++++++++++++++++++++
> hw/xfree86/parser/configProcs.h | 5 ++
> hw/xfree86/parser/read.c | 6 ++
> hw/xfree86/parser/write.c | 2 +
> hw/xfree86/parser/xf86Parser.h | 9 +++
> 7 files changed, 264 insertions(+)
> create mode 100644 hw/xfree86/parser/OutputClass.c
>
> diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
> index 85f9f2ee1331..0db87bb31404 100644
> --- a/hw/xfree86/man/xorg.conf.man
> +++ b/hw/xfree86/man/xorg.conf.man
> @@ -171,6 +171,7 @@ The section names are:
> .BR "Extensions " "Extension enabling"
> .BR "InputDevice " "Input device description"
> .BR "InputClass " "Input class description"
> +.BR "OutputClass " "Output class description"
> .BR "Device " "Graphics device description"
> .BR "VideoAdaptor " "Xv video adaptor description"
> .BR "Monitor " "Monitor description"
> @@ -1186,6 +1187,79 @@ entries.
> This optional entry specifies that the device should be ignored entirely,
> and not added to the server. This can be useful when the device is handled
> by another program and no X events should be generated.
> +.SH "OUTPUTCLASS SECTION"
> +The config file may have multiple
> +.B OutputClass
> +sections.
> +These sections are optional and are used to provide configuration for a
> +class of output devices as they are automatically added. An output device can
I think technically, sentences in ROFF syntax should start on their own
lines.
> +match more than one
> +.B OutputClass
> +section. Each class can override settings from a previous class, so it is
> +best to arrange the sections with the most generic matches first.
> +.PP
> +.B OutputClass
> +sections have the following format:
> +.PP
> +.RS 4
> +.nf
> +.B "Section \*qOutputClass\*q"
> +.BI " Identifier \*q" name \*q
> +.I " entries"
> +.I " ..."
> +.B "EndSection"
> +.fi
> +.RE
> +.PP
> +The
> +.B Identifier
> +entry is required in all
> +.B OutputClass
> +sections.
> +All other entries are optional.
> +.PP
> +The
> +.B Identifier
> +entry specifies the unique name for this output class.
> +The
> +.B Driver
> +entry specifies the name of the driver to use for this input device.
s/input/output/ here.
> +After all classes have been examined, the
> +.RI \*q outputdriver \*q
> +module from the first
> +.B Driver
> +entry will be enabled when using the loadable server.
> +.PP
> +When an output device is automatically added, its characteristics are
> +checked against all
> +.B OutputClass
> +sections. Each section can contain optional entries to narrow the match
> +of the class. If none of the optional entries appear, the
> +.B OutputClass
> +section is generic and will match any input device. If more than one of
also here.
> +these entries appear, they all must match for the configuration to apply.
> +.PP
> +The following list of tokens can be matched against attributes of the device.
> +An entry can be constructed to match attributes from different devices by
> +separating arguments with a '|' character.
> +.PP
> +For example:
> +.PP
> +.RS 4
> +.nf
> +.B "Section \*qOutputClass\*q"
> +.B " Identifier \*qMy Class\*q"
> +.B " # kernel driver must be either foo or bar
> +.B " MatchDriver \*qfoo|bar\*q
> +.I " ..."
> +.B "EndSection"
> +.fi
> +.RE
> +.TP 7
> +.BI "MatchDriver \*q" matchdriver \*q
> +Check the case-sensitive string
> +.RI \*q matchdriver \*q
> +against the kernel driver of the device.
> .SH "DEVICE SECTION"
> The config file may have multiple
> .B Device
> diff --git a/hw/xfree86/parser/Makefile.am b/hw/xfree86/parser/Makefile.am
> index 3bf62e8af6a5..4d0bb4fd8e01 100644
> --- a/hw/xfree86/parser/Makefile.am
> +++ b/hw/xfree86/parser/Makefile.am
> @@ -14,6 +14,7 @@ INTERNAL_SOURCES= \
> Flags.c \
> Input.c \
> InputClass.c \
> + OutputClass.c \
> Layout.c \
> Module.c \
> Video.c \
> diff --git a/hw/xfree86/parser/OutputClass.c b/hw/xfree86/parser/OutputClass.c
> new file mode 100644
> index 000000000000..7e9a8ac1a8c0
> --- /dev/null
> +++ b/hw/xfree86/parser/OutputClass.c
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright (c) 2014 NVIDIA Corporation. All rights reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following
> + * conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#ifdef HAVE_XORG_CONFIG_H
> +#include <xorg-config.h>
> +#endif
> +
> +#include "os.h"
> +#include "xf86Parser.h"
> +#include "xf86tokens.h"
> +#include "Configint.h"
> +
> +static
> +xf86ConfigSymTabRec OutputClassTab[] = {
> + {ENDSECTION, "endsection"},
> + {IDENTIFIER, "identifier"},
> + {DRIVER, "driver"},
> + {MATCH_DRIVER, "matchdriver"},
> + {-1, ""},
> +};
> +
> +#define CLEANUP xf86freeOutputClassList
> +
> +#define TOKEN_SEP "|"
> +
> +static void
> +add_group_entry(struct xorg_list *head, char **values)
> +{
> + xf86MatchGroup *group;
> +
> + group = malloc(sizeof(*group));
> + if (group) {
> + group->values = values;
> + xorg_list_add(&group->entry, head);
> + }
> +}
> +
> +XF86ConfOutputClassPtr
> +xf86parseOutputClassSection(void)
> +{
> + int has_ident = FALSE;
> + int token;
> +
> + parsePrologue(XF86ConfOutputClassPtr, XF86ConfOutputClassRec)
> +
> + /* Initialize MatchGroup lists */
> + xorg_list_init(&ptr->match_driver);
> +
> + while ((token = xf86getToken(OutputClassTab)) != ENDSECTION) {
> + switch (token) {
> + case COMMENT:
> + ptr->comment = xf86addComment(ptr->comment, xf86_lex_val.str);
> + break;
> + case IDENTIFIER:
> + if (xf86getSubToken(&(ptr->comment)) != STRING)
> + Error(QUOTE_MSG, "Identifier");
> + if (has_ident == TRUE)
> + Error(MULTIPLE_MSG, "Identifier");
> + ptr->identifier = xf86_lex_val.str;
> + has_ident = TRUE;
> + break;
> + case DRIVER:
> + if (xf86getSubToken(&(ptr->comment)) != STRING)
> + Error(QUOTE_MSG, "Driver");
> + else
> + ptr->driver = xf86_lex_val.str;
> + break;
> + case MATCH_DRIVER:
> + if (xf86getSubToken(&(ptr->comment)) != STRING)
> + Error(QUOTE_MSG, "MatchDriver");
> + add_group_entry(&ptr->match_driver,
> + xstrtokenize(xf86_lex_val.str, TOKEN_SEP));
> + free(xf86_lex_val.str);
> + break;
> + case EOF_TOKEN:
> + Error(UNEXPECTED_EOF_MSG);
> + break;
> + default:
> + Error(INVALID_KEYWORD_MSG, xf86tokenString());
> + break;
> + }
> + }
> +
> + if (!has_ident)
> + Error(NO_IDENT_MSG);
> +
> +#ifdef DEBUG
> + printf("OutputClass section parsed\n");
> +#endif
> +
> + return ptr;
> +}
> +void
> +xf86printOutputClassSection(FILE * cf, XF86ConfOutputClassPtr ptr)
> +{
> + const xf86MatchGroup *group;
> + char *const *cur;
> +
> + while (ptr) {
> + fprintf(cf, "Section \"OutputClass\"\n");
> + if (ptr->comment)
> + fprintf(cf, "%s", ptr->comment);
> + if (ptr->identifier)
> + fprintf(cf, "\tIdentifier \"%s\"\n", ptr->identifier);
> + if (ptr->driver)
> + fprintf(cf, "\tDriver \"%s\"\n", ptr->driver);
> +
> + xorg_list_for_each_entry(group, &ptr->match_driver, entry) {
> + fprintf(cf, "\tMatchDriver \"");
> + for (cur = group->values; *cur; cur++)
> + fprintf(cf, "%s%s", cur == group->values ? "" : TOKEN_SEP,
> + *cur);
> + fprintf(cf, "\"\n");
> + }
> +
> + fprintf(cf, "EndSection\n\n");
> + ptr = ptr->list.next;
> + }
> +}
> +
> +void
> +xf86freeOutputClassList(XF86ConfOutputClassPtr ptr)
> +{
> + XF86ConfOutputClassPtr prev;
> +
> + while (ptr) {
> + xf86MatchGroup *group, *next;
> + char **list;
> +
> + TestFree(ptr->identifier);
> + TestFree(ptr->comment);
> + TestFree(ptr->driver);
> +
> + xorg_list_for_each_entry_safe(group, next, &ptr->match_driver, entry) {
> + xorg_list_del(&group->entry);
> + for (list = group->values; *list; list++)
> + free(*list);
> + free(group);
> + }
> +
> + prev = ptr;
> + ptr = ptr->list.next;
> + free(prev);
> + }
> +}
> diff --git a/hw/xfree86/parser/configProcs.h b/hw/xfree86/parser/configProcs.h
> index 60509dcd8552..774e2a2da0b0 100644
> --- a/hw/xfree86/parser/configProcs.h
> +++ b/hw/xfree86/parser/configProcs.h
> @@ -57,6 +57,11 @@ XF86ConfInputClassPtr xf86parseInputClassSection(void);
> void xf86printInputClassSection(FILE * f, XF86ConfInputClassPtr ptr);
> void xf86freeInputClassList(XF86ConfInputClassPtr ptr);
>
> +/* OutputClass.c */
> +XF86ConfOutputClassPtr xf86parseOutputClassSection(void);
> +void xf86printOutputClassSection(FILE * f, XF86ConfOutputClassPtr ptr);
> +void xf86freeOutputClassList(XF86ConfOutputClassPtr ptr);
> +
> /* Layout.c */
> XF86ConfLayoutPtr xf86parseLayoutSection(void);
> void xf86printLayoutSection(FILE * cf, XF86ConfLayoutPtr ptr);
> diff --git a/hw/xfree86/parser/read.c b/hw/xfree86/parser/read.c
> index 2478b074b4ac..22f6e6af4d00 100644
> --- a/hw/xfree86/parser/read.c
> +++ b/hw/xfree86/parser/read.c
> @@ -165,6 +165,12 @@ xf86readConfigFile(void)
> HANDLE_LIST(conf_inputclass_lst,
> xf86parseInputClassSection, XF86ConfInputClassPtr);
> }
> + else if (xf86nameCompare(xf86_lex_val.str, "outputclass") == 0) {
> + free(xf86_lex_val.str);
> + xf86_lex_val.str = NULL;
> + HANDLE_LIST(conf_outputclass_lst, xf86parseOutputClassSection,
> + XF86ConfOutputClassPtr);
> + }
> else if (xf86nameCompare(xf86_lex_val.str, "module") == 0) {
> free(xf86_lex_val.str);
> xf86_lex_val.str = NULL;
> diff --git a/hw/xfree86/parser/write.c b/hw/xfree86/parser/write.c
> index 26739b933087..472b27ba1b5b 100644
> --- a/hw/xfree86/parser/write.c
> +++ b/hw/xfree86/parser/write.c
> @@ -114,6 +114,8 @@ doWriteConfigFile(const char *filename, XF86ConfigPtr cptr)
>
> xf86printInputClassSection(cf, cptr->conf_inputclass_lst);
>
> + xf86printOutputClassSection(cf, cptr->conf_outputclass_lst);
> +
> xf86printVideoAdaptorSection(cf, cptr->conf_videoadaptor_lst);
>
> xf86printModesSection(cf, cptr->conf_modes_lst);
> diff --git a/hw/xfree86/parser/xf86Parser.h b/hw/xfree86/parser/xf86Parser.h
> index 8f855ac098ff..3a425c52bb7a 100644
> --- a/hw/xfree86/parser/xf86Parser.h
> +++ b/hw/xfree86/parser/xf86Parser.h
> @@ -325,6 +325,14 @@ typedef struct {
> char *comment;
> } XF86ConfInputClassRec, *XF86ConfInputClassPtr;
>
> +typedef struct {
> + GenericListRec list;
> + char *identifier;
> + char *driver;
> + struct xorg_list match_driver;
> + char *comment;
> +} XF86ConfOutputClassRec, *XF86ConfOutputClassPtr;
> +
> /* Values for adj_where */
> #define CONF_ADJ_OBSOLETE -1
> #define CONF_ADJ_ABSOLUTE 0
> @@ -408,6 +416,7 @@ typedef struct {
> XF86ConfScreenPtr conf_screen_lst;
> XF86ConfInputPtr conf_input_lst;
> XF86ConfInputClassPtr conf_inputclass_lst;
> + XF86ConfOutputClassPtr conf_outputclass_lst;
> XF86ConfLayoutPtr conf_layout_lst;
> XF86ConfVendorPtr conf_vendor_lst;
> XF86ConfDRIPtr conf_dri;
> --
> 1.8.4.2
More information about the xorg-devel
mailing list