On Wed, Jun 25, 2014 at 9:55 AM, Thierry Reding <[email protected]> wrote: > From: Thierry Reding <[email protected]> > > 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. > > Reviewed-by: Aaron Plattner <[email protected]> > Tested-By: Aaron Plattner <[email protected]> > Signed-off-by: Thierry Reding <[email protected]>
Tested-by: Rob Clark <[email protected]> > --- > hw/xfree86/man/xorg.conf.man | 77 ++++++++++++++++++ > 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, 267 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 cadd87b7baf6..bc33df197a21 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" > @@ -1190,6 +1191,82 @@ 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 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 output device. > +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 output device. > +If more than one of 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 c95423a1faa7..3fa5b716d69f 100644 > --- a/hw/xfree86/parser/xf86Parser.h > +++ b/hw/xfree86/parser/xf86Parser.h > @@ -327,6 +327,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 > @@ -411,6 +419,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; > -- > 2.0.0 > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
