diff --git a/commitFile.txt b/commitFile.txt new file mode 100644 index 0000000..6aab2fe --- /dev/null +++ b/commitFile.txt @@ -0,0 +1,52 @@ +Updating prebuilts and/or headers + +6f6f68f976250f2646450e571f9ab2d7eee1ac80 - nvidia-xconfig-540.3.0/nvidia-cfg.h +46f2ea329459b0b16cb36cc14cec0de737d0963e - nvidia-xconfig-540.3.0/options.c +9b0c02164398be2795fea7cb13c9e1b062d24bfb - nvidia-xconfig-540.3.0/query_gpu_info.c +b1bc157844c5570f911b2bf45249bd26ce73efef - nvidia-xconfig-540.3.0/Makefile +10edc2c301fd331439b38d001c0df41669c238b2 - nvidia-xconfig-540.3.0/multiple_screens.c +f14e9577e537037d4778d490ef70f13b0e94a70a - nvidia-xconfig-540.3.0/option_table.h +1e39095238886dfc6a69f7ec750e10c05a93e7d1 - nvidia-xconfig-540.3.0/nvidia-xconfig.1.m4 +913b088cb559f31e09a1baf89d85d75cb43079b4 - nvidia-xconfig-540.3.0/nvidia-xconfig.h +647e7896275a1113ec99352d573823a05001f57e - nvidia-xconfig-540.3.0/lscf.c +bfa37f78ba458f14a1865bbf3f67eb84987a7e1c - nvidia-xconfig-540.3.0/extract_edids.c +41bcac41393c9a465c30c07cf1ab386647a16687 - nvidia-xconfig-540.3.0/util.c +a5ad539267b73169480e7898b284823639c4db3a - nvidia-xconfig-540.3.0/tree.c +4cc77b90af91e615a64ae04893fdffa7939db84c - nvidia-xconfig-540.3.0/COPYING +c946eefad99cec9366d8abbd4e45c5d138d3b7be - nvidia-xconfig-540.3.0/make_usable.c +d37da5a118e0418b267a48d05fd144611316b42c - nvidia-xconfig-540.3.0/gen-manpage-opts.c +b3d0f9f27c4d9cb7940d04e1dd387d357a16024c - nvidia-xconfig-540.3.0/nvidia-xconfig.c +524990f5497f9bbeb3d148b5e7dc8d2267c3163d - nvidia-xconfig-540.3.0/common-utils/nvpci-utils.c +abb5c1b445d9353f2d2840bda848cd16109710a4 - nvidia-xconfig-540.3.0/common-utils/msg.h +1654638c567bc7f2bd70b54d807b498ab14c1061 - nvidia-xconfig-540.3.0/common-utils/nvpci-utils.h +8a346196b052cfb1e06dd83d2ad1fe71e928d2b3 - nvidia-xconfig-540.3.0/common-utils/common-utils.c +e572cac43202f6c2af1c80b9e3901215126093ed - nvidia-xconfig-540.3.0/common-utils/nvgetopt.h +8db48a58d1654ed69920366bef10f38b789a1a84 - nvidia-xconfig-540.3.0/common-utils/msg.c +8259a24058c714629f9819cc8c830ea9b202bb27 - nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.h +5d55b94375c2055cfa1578e4c7f34c90e63a33f7 - nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.c +dc2678d8a9d794a4b2b2718fce57ec087f21f54b - nvidia-xconfig-540.3.0/common-utils/common-utils.h +384e36102dcd08ed4c5de05b5e3b8a7cdb2e257d - nvidia-xconfig-540.3.0/common-utils/nvgetopt.c +33211ca0a10f50e2c87b9e8feef6c1ab381b57a1 - nvidia-xconfig-540.3.0/XF86Config-parser/DRI.c +5ffb2caa5077a2e6ec1c5ece807e71503fb2fbce - nvidia-xconfig-540.3.0/XF86Config-parser/Module.c +953b945f3b117d6fb44f1f738af17b6380a9ec72 - nvidia-xconfig-540.3.0/XF86Config-parser/Monitor.c +de1c758e29f217e1a99e4c076d54ac84bce98b18 - nvidia-xconfig-540.3.0/XF86Config-parser/Screen.c +f3d611bdbddfa64675a0810ef81dada57e224bcd - nvidia-xconfig-540.3.0/XF86Config-parser/Extensions.c +ec19d673a6a7d1d8f855f2d32d3e8f63046c3625 - nvidia-xconfig-540.3.0/XF86Config-parser/Files.c +e67d630ef396ab7d34524c333f3a77fc42ba8fc6 - nvidia-xconfig-540.3.0/XF86Config-parser/configProcs.h +c66a0a141e25e31b568fb9df41f17d7fb9e6d3b9 - nvidia-xconfig-540.3.0/XF86Config-parser/xf86Parser.h +4d9b03ea3badceb6bdfdf6589e6731140ec44079 - nvidia-xconfig-540.3.0/XF86Config-parser/Generate.c +cda3a4ab05bf48ba28af35b5c4c632e968afc7fa - nvidia-xconfig-540.3.0/XF86Config-parser/Util.c +83b0a8efd6a508db54995688ab353591bdb242a2 - nvidia-xconfig-540.3.0/XF86Config-parser/Flags.c +45ceb0129668346ae3e52d81bb6e2f97efadf9d0 - nvidia-xconfig-540.3.0/XF86Config-parser/Input.c +18711ff932af2202869a30f3b32d6d7fe7811c84 - nvidia-xconfig-540.3.0/XF86Config-parser/Layout.c +c7b8d8ca0f7c9dcc2cdca4f8e77d1122c71892ef - nvidia-xconfig-540.3.0/XF86Config-parser/Read.c +0a274c4bc54b6ae0f6d009e443bda0cb033d66b5 - nvidia-xconfig-540.3.0/XF86Config-parser/Pointer.c +04efe162cf6d97882f2bb87f3712d9a65c2320f3 - nvidia-xconfig-540.3.0/XF86Config-parser/Scan.c +7344be997921dec57959691e986763ee686888d5 - nvidia-xconfig-540.3.0/XF86Config-parser/Device.c +4407207cf890539dc604cff5b834c994b307729a - nvidia-xconfig-540.3.0/XF86Config-parser/Write.c +3f2238c88d737bd329a9bca1ac4b0bcf77bb9ac2 - nvidia-xconfig-540.3.0/XF86Config-parser/xf86tokens.h +a9bc06f33bf525c2b08be2dc3cd64a59c4c7946d - nvidia-xconfig-540.3.0/XF86Config-parser/Configint.h +9cbc29da282aa957f28b7fc83caf1e3b19ee2a52 - nvidia-xconfig-540.3.0/XF86Config-parser/Vendor.c +2022a4a3c2a1b23a67ae74f50a3849f5f3a45e4b - nvidia-xconfig-540.3.0/XF86Config-parser/Keyboard.c +6c210ad0eaee1db3fec48ff01746cb054b4f9aaa - nvidia-xconfig-540.3.0/XF86Config-parser/Video.c +ac878b26ded86a3c502a6a81fc4c4a96162afefb - nvidia-xconfig-540.3.0/XF86Config-parser/Merge.c diff --git a/nvidia-xconfig-540.3.0/COPYING b/nvidia-xconfig-540.3.0/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/nvidia-xconfig-540.3.0/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/nvidia-xconfig-540.3.0/Makefile b/nvidia-xconfig-540.3.0/Makefile new file mode 100644 index 0000000..92dbbc6 --- /dev/null +++ b/nvidia-xconfig-540.3.0/Makefile @@ -0,0 +1,172 @@ +# +# nvidia-xconfig: A tool for manipulating X config files, +# specifically for use by the NVIDIA Linux graphics driver. +# +# Copyright (C) 2008 NVIDIA Corporation +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# +# Makefile +# + + +############################################################################## +# include common variables and functions +############################################################################## + +COMMON_UTILS_PCIACCESS = 1 +include utils.mk + + +############################################################################## +# The calling Makefile may export any of the following variables; we +# assign default values if they are not exported by the caller +############################################################################## + +NVIDIA_CFG_DIR ?= . + + +############################################################################## +# assign variables +############################################################################## + +NVIDIA_XCONFIG = $(OUTPUTDIR)/nvidia-xconfig + +NVIDIA_XCONFIG_PROGRAM_NAME = "nvidia-xconfig" + +NVIDIA_XCONFIG_VERSION := $(NVIDIA_VERSION) + +MANPAGE_GZIP ?= 1 + +MANPAGE_not_gzipped = $(OUTPUTDIR)/nvidia-xconfig.1 +MANPAGE_gzipped = $(OUTPUTDIR)/nvidia-xconfig.1.gz +ifeq ($(MANPAGE_GZIP),1) + MANPAGE = $(MANPAGE_gzipped) +else + MANPAGE = $(MANPAGE_not_gzipped) +endif +GEN_MANPAGE_OPTS = $(OUTPUTDIR_ABSOLUTE)/gen-manpage-opts +OPTIONS_1_INC = $(OUTPUTDIR)/options.1.inc + + +############################################################################## +# The common-utils directory may be in one of two places: either +# elsewhere in the driver source tree when building nvidia-xconfig as +# part of the NVIDIA driver build (in which case, COMMON_UTILS_DIR +# should be defined by the calling makefile), or directly in the +# source directory when building from the nvidia-xconfig source +# tarball (in which case, the below conditional assignment should be +# used) +############################################################################## + +COMMON_UTILS_DIR ?= common-utils + +include dist-files.mk + +include $(COMMON_UTILS_DIR)/src.mk +SRC += $(addprefix $(COMMON_UTILS_DIR)/,$(COMMON_UTILS_SRC)) + +OBJS = $(call BUILD_OBJECT_LIST,$(SRC)) + +common_cflags += -I XF86Config-parser +common_cflags += -I $(OUTPUTDIR) +common_cflags += -I $(NVIDIA_CFG_DIR) +common_cflags += -I $(COMMON_UTILS_DIR) +common_cflags += -DPROGRAM_NAME=\"nvidia-xconfig\" + +CFLAGS += $(common_cflags) +HOST_CFLAGS += $(common_cflags) + +LIBS += -lm -lpciaccess + +ifneq ($(TARGET_OS),FreeBSD) + LIBS += -ldl +endif + +ifeq ($(TARGET_OS),SunOS) + LIBS += -lscf -ldevinfo +endif + + +############################################################################## +# build rules +############################################################################## + +.PHONY: all +all: $(NVIDIA_XCONFIG) $(MANPAGE) + +.PHONY: install +install: NVIDIA_XCONFIG_install MANPAGE_install + +.PHONY: NVIDIA_XCONFIG_install +NVIDIA_XCONFIG_install: $(NVIDIA_XCONFIG) + $(MKDIR) $(BINDIR) + $(INSTALL) $(INSTALL_BIN_ARGS) $< $(BINDIR)/$(notdir $<) + +.PHONY: MANPAGE_install +MANPAGE_install: $(MANPAGE) + $(MKDIR) $(MANDIR) + $(INSTALL) $(INSTALL_DOC_ARGS) $< $(MANDIR)/$(notdir $<) + +$(eval $(call DEBUG_INFO_RULES, $(NVIDIA_XCONFIG))) +$(NVIDIA_XCONFIG).unstripped: $(OBJS) + $(call quiet_cmd,LINK) $(CFLAGS) $(LDFLAGS) $(BIN_LDFLAGS) \ + $(PCIACCESS_LDFLAGS) -o $@ $(OBJS) $(LIBS) + +# make_usable.c includes pciaccess.h +$(call BUILD_OBJECT_LIST,make_usable.c): CFLAGS += $(PCIACCESS_CFLAGS) + +# define the rule to build each object file +$(foreach src, $(SRC), $(eval $(call DEFINE_OBJECT_RULE,TARGET,$(src)))) + +.PHONY: clean clobber +clean clobber: + $(RM) -rf $(NVIDIA_XCONFIG) $(MANPAGE) *~ \ + $(OUTPUTDIR)/*.o $(OUTPUTDIR)/*.d \ + $(GEN_MANPAGE_OPTS) $(OPTIONS_1_INC) + + +############################################################################## +# Documentation +############################################################################## + +AUTO_TEXT = ".\\\" WARNING: THIS FILE IS AUTO-GENERATED! Edit $< instead." + +.PHONY: doc +doc: $(MANPAGE) + +GEN_MANPAGE_OPTS_SRC = gen-manpage-opts.c +GEN_MANPAGE_OPTS_SRC += $(COMMON_UTILS_DIR)/gen-manpage-opts-helper.c + +GEN_MANPAGE_OPTS_OBJS = $(call BUILD_OBJECT_LIST,$(GEN_MANPAGE_OPTS_SRC)) + +$(foreach src, $(GEN_MANPAGE_OPTS_SRC), \ + $(eval $(call DEFINE_OBJECT_RULE,HOST,$(src)))) + +$(GEN_MANPAGE_OPTS): $(GEN_MANPAGE_OPTS_OBJS) + $(call quiet_cmd,HOST_LINK) \ + $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_BIN_LDFLAGS) $^ -o $@ + +$(OPTIONS_1_INC): $(GEN_MANPAGE_OPTS) + @$< > $@ + +$(MANPAGE_not_gzipped): nvidia-xconfig.1.m4 $(OPTIONS_1_INC) $(VERSION_MK) + $(call quiet_cmd,M4) -D__HEADER__=$(AUTO_TEXT) -I $(OUTPUTDIR) \ + -D__VERSION__=$(NVIDIA_VERSION) \ + -D__DATE__="`$(DATE) +%F`" \ + -D__BUILD_OS__=$(TARGET_OS) \ + $< > $@ + +$(MANPAGE_gzipped): $(MANPAGE_not_gzipped) + $(GZIP_CMD) -9nf < $< > $@ diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Configint.h b/nvidia-xconfig-540.3.0/XF86Config-parser/Configint.h new file mode 100644 index 0000000..b626bb2 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Configint.h @@ -0,0 +1,211 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2002 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* + * These definitions are used through out the configuration file parser, but + * they should not be visible outside of the parser. + */ + +#ifndef _Configint_h_ +#define _Configint_h_ + +#include +#include +#include +#include +#include "xf86Parser.h" + +typedef struct +{ + int num; /* returned number */ + char *str; /* private copy of the return-string */ + double realnum; /* returned number as a real */ +} +LexRec, *LexPtr; + + +#include "configProcs.h" +#include + +#define TEST_FREE(a) \ + if (a) { \ + free (a); \ + a = NULL; \ + } + + +#define PARSE_PROLOGUE(typeptr,typerec) \ + typeptr ptr; \ + if ((ptr = (typeptr) calloc(1, sizeof(typerec))) == NULL) { \ + return NULL; \ + } \ + memset(ptr, 0, sizeof(typerec)); + + +#define HANDLE_LIST(field,func,type) \ +{ \ + type p = func(); \ + if (p == NULL) { \ + CLEANUP (&ptr); \ + return (NULL); \ + } else { \ + xconfigAddListItem((GenericListPtr*)(&ptr->field), \ + (GenericListPtr) p); \ + } \ +} + + +#define Error(a,b) \ + do { \ + xconfigErrorMsg(ParseErrorMsg, a, b); \ + CLEANUP (&ptr); \ + return NULL; \ + } while (0) + + +/* + * These are defines for error messages to promote consistency. + * error messages are preceded by the line number, section and file name, + * so these messages should be about the specific keyword and syntax in error. + * To help limit namespace polution, end each with _MSG. + * limit messages to 70 characters if possible. + */ + +#define BAD_OPTION_MSG \ +"The Option keyword requires 1 or 2 quoted strings to follow it." +#define INVALID_KEYWORD_MSG \ +"\"%s\" is not a valid keyword in this section." +#define INVALID_SECTION_MSG \ +"\"%s\" is not a valid section name." +#define UNEXPECTED_EOF_MSG \ +"Unexpected EOF. Missing EndSection keyword?" +#define QUOTE_MSG \ +"The %s keyword requires a quoted string to follow it." +#define NUMBER_MSG \ +"The %s keyword requires a number to follow it." +#define POSITIVE_INT_MSG \ +"The %s keyword requires a positive integer to follow it." +#define ZAXISMAPPING_MSG \ +"The ZAxisMapping keyword requires 2 positive numbers or X or Y to follow it." +#define AUTOREPEAT_MSG \ +"The AutoRepeat keyword requires 2 numbers (delay and rate) to follow it." +#define XLEDS_MSG \ +"The XLeds keyword requries one or more numbers to follow it." +#define DACSPEED_MSG \ +"The DacSpeed keyword must be followed by a list of up to %d numbers." +#define DISPLAYSIZE_MSG \ +"The DisplaySize keyword must be followed by the width and height in mm." +#define HORIZSYNC_MSG \ +"The HorizSync keyword must be followed by a list of numbers or ranges." +#define VERTREFRESH_MSG \ +"The VertRefresh keyword must be followed by a list of numbers or ranges." +#define VIEWPORT_MSG \ +"The Viewport keyword must be followed by an X and Y value." +#define VIRTUAL_MSG \ +"The Virtual keyword must be followed by a width and height value." +#define WEIGHT_MSG \ +"The Weight keyword must be followed by red, green and blue values." +#define BLACK_MSG \ +"The Black keyword must be followed by red, green and blue values." +#define WHITE_MSG \ +"The White keyword must be followed by red, green and blue values." +#define SCREEN_MSG \ +"The Screen keyword must be followed by an optional number, a screen name\n" \ +"\tin quotes, and optional position/layout information." +#define INVALID_SCR_MSG \ +"Invalid Screen line." +#define INPUTDEV_MSG \ +"The InputDevice keyword must be followed by an input device name in quotes." +#define INACTIVE_MSG \ +"The Inactive keyword must be followed by a Device name in quotes." +#define UNDEFINED_SCREEN_MSG \ +"Undefined Screen \"%s\" referenced by ServerLayout \"%s\"." +#define UNDEFINED_MONITOR_MSG \ +"Undefined Monitor \"%s\" referenced by Screen \"%s\"." +#define UNDEFINED_MODES_MSG \ +"Undefined Modes Section \"%s\" referenced by Monitor \"%s\"." +#define UNDEFINED_DEVICE_MSG \ +"Undefined Device \"%s\" referenced by Screen \"%s\"." +#define UNDEFINED_ADAPTOR_MSG \ +"Undefined VideoAdaptor \"%s\" referenced by Screen \"%s\"." +#define ADAPTOR_REF_TWICE_MSG \ +"VideoAdaptor \"%s\" already referenced by Screen \"%s\"." +#define UNDEFINED_DEVICE_LAY_MSG \ +"Undefined Device \"%s\" referenced by ServerLayout \"%s\"." +#define UNDEFINED_INPUT_MSG \ +"Undefined InputDevice \"%s\" referenced by ServerLayout \"%s\"." +#define NO_IDENT_MSG \ +"This section must have an Identifier line." +#define ONLY_ONE_MSG \ +"This section must have only one of either %s line." +#define UNDEFINED_DRIVER_MSG \ +"Device section \"%s\" must have a Driver line." +#define UNDEFINED_INPUTDRIVER_MSG \ +"InputDevice section \"%s\" must have a Driver line." +#define INVALID_GAMMA_MSG \ +"gamma correction value(s) expected\n either one value or three r/g/b values." +#define GROUP_MSG \ +"The Group keyword must be followed by either a group name in quotes or\n" \ +"\ta numerical group id." +#define MULTIPLE_MSG \ +"Multiple \"%s\" lines." + +/* Warning messages */ +#define OBSOLETE_MSG \ +"Ignoring obsolete keyword \"%s\"." +#define MOVED_TO_FLAGS_MSG \ +"Keyword \"%s\" is now an Option flag in the ServerFlags section." + +#endif /* _Configint_h_ */ diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/DRI.c b/nvidia-xconfig-540.3.0/XF86Config-parser/DRI.c new file mode 100644 index 0000000..b032ced --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/DRI.c @@ -0,0 +1,158 @@ +/* DRI.c -- DRI Section in XF86Config file + * Created: Fri Mar 19 08:40:22 1999 by faith@precisioninsight.com + * Revised: Thu Jun 17 16:08:05 1999 by faith@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * 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 (including the next + * paragraph) 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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + * + */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec DRITab[] = +{ + {ENDSECTION, "endsection"}, + {GROUP, "group"}, + {BUFFERS, "buffers"}, + {MODE, "mode"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeBuffersList + +XConfigBuffersPtr +xconfigParseBuffers (void) +{ + int token; + PARSE_PROLOGUE (XConfigBuffersPtr, XConfigBuffersRec); + + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) { + Error("Buffers count expected", NULL); + } + ptr->count = val.num; + + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) { + Error("Buffers size expected", NULL); + } + ptr->size = val.num; + + if ((token = xconfigGetSubToken (&(ptr->comment))) == STRING) { + ptr->flags = val.str; + if ((token = xconfigGetToken (NULL)) == COMMENT) + ptr->comment = xconfigAddComment(ptr->comment, val.str); + else + xconfigUnGetToken(token); + } + + return ptr; +} + +#undef CLEANUP + +#define CLEANUP xconfigFreeDRI + +XConfigDRIPtr +xconfigParseDRISection (void) +{ + int token; + PARSE_PROLOGUE (XConfigDRIPtr, XConfigDRIRec); + + /* Zero is a valid value for this. */ + ptr->group = -1; + while ((token = xconfigGetToken (DRITab)) != ENDSECTION) { + switch (token) + { + case GROUP: + if ((token = xconfigGetSubToken (&(ptr->comment))) == STRING) + ptr->group_name = val.str; + else if (token == NUMBER) + ptr->group = val.num; + else + Error (GROUP_MSG, NULL); + break; + case MODE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "Mode"); + ptr->mode = val.num; + break; + case BUFFERS: + HANDLE_LIST (buffers, xconfigParseBuffers, + XConfigBuffersPtr); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintDRISection (FILE * cf, XConfigDRIPtr ptr) +{ + /* we never need the DRI section for the NVIDIA driver */ + + return; +} + +void +xconfigFreeDRI (XConfigDRIPtr *ptr) +{ + if (ptr == NULL || *ptr == NULL) + return; + + xconfigFreeBuffersList (&((*ptr)->buffers)); + TEST_FREE ((*ptr)->comment); + free (*ptr); + *ptr = NULL; +} + +void +xconfigFreeBuffersList (XConfigBuffersPtr *ptr) +{ + XConfigBuffersPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) { + TEST_FREE ((*ptr)->flags); + TEST_FREE ((*ptr)->comment); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Device.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Device.c new file mode 100644 index 0000000..c31d5f5 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Device.c @@ -0,0 +1,539 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +#include + +extern LexRec val; + +static +XConfigSymTabRec DeviceTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {VENDOR, "vendorname"}, + {BOARD, "boardname"}, + {CHIPSET, "chipset"}, + {RAMDAC, "ramdac"}, + {DACSPEED, "dacspeed"}, + {CLOCKS, "clocks"}, + {OPTION, "option"}, + {VIDEORAM, "videoram"}, + {BIOSBASE, "biosbase"}, + {MEMBASE, "membase"}, + {IOBASE, "iobase"}, + {CLOCKCHIP, "clockchip"}, + {CHIPID, "chipid"}, + {CHIPREV, "chiprev"}, + {CARD, "card"}, + {DRIVER, "driver"}, + {BUSID, "busid"}, + {TEXTCLOCKFRQ, "textclockfreq"}, + {IRQ, "irq"}, + {SCREEN, "screen"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeDeviceList + +XConfigDevicePtr +xconfigParseDeviceSection (void) +{ + int i; + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigDevicePtr, XConfigDeviceRec) + + /* Zero is a valid value for these */ + ptr->chipid = -1; + ptr->chiprev = -1; + ptr->irq = -1; + ptr->screen = -1; + while ((token = xconfigGetToken (DeviceTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case VENDOR: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Vendor"); + ptr->vendor = val.str; + break; + case BOARD: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Board"); + ptr->board = val.str; + break; + case CHIPSET: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Chipset"); + ptr->chipset = val.str; + break; + case CARD: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Card"); + ptr->card = val.str; + break; + case DRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Driver"); + ptr->driver = val.str; + break; + case RAMDAC: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Ramdac"); + ptr->ramdac = val.str; + break; + case DACSPEED: + for (i = 0; i < CONF_MAXDACSPEEDS; i++) + ptr->dacSpeeds[i] = 0; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + { + Error (DACSPEED_MSG, CONF_MAXDACSPEEDS); + } + else + { + ptr->dacSpeeds[0] = (int) (val.realnum * 1000.0 + 0.5); + for (i = 1; i < CONF_MAXDACSPEEDS; i++) + { + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->dacSpeeds[i] = (int) + (val.realnum * 1000.0 + 0.5); + else + { + xconfigUnGetToken (token); + break; + } + } + } + break; + case VIDEORAM: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "VideoRam"); + ptr->videoram = val.num; + break; + case BIOSBASE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "BIOSBase"); + ptr->bios_base = val.num; + break; + case MEMBASE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "MemBase"); + ptr->mem_base = val.num; + break; + case IOBASE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "IOBase"); + ptr->io_base = val.num; + break; + case CLOCKCHIP: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "ClockChip"); + ptr->clockchip = val.str; + break; + case CHIPID: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "ChipID"); + ptr->chipid = val.num; + break; + case CHIPREV: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "ChipRev"); + ptr->chiprev = val.num; + break; + + case CLOCKS: + token = xconfigGetSubToken(&(ptr->comment)); + for( i = ptr->clocks; + token == NUMBER && i < CONF_MAXCLOCKS; i++ ) { + ptr->clock[i] = (int)(val.realnum * 1000.0 + 0.5); + token = xconfigGetSubToken(&(ptr->comment)); + } + ptr->clocks = i; + xconfigUnGetToken (token); + break; + case TEXTCLOCKFRQ: + if ((token = xconfigGetSubToken(&(ptr->comment))) != NUMBER) + Error (NUMBER_MSG, "TextClockFreq"); + ptr->textclockfreq = (int)(val.realnum * 1000.0 + 0.5); + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case BUSID: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "BusID"); + ptr->busid = val.str; + break; + case IRQ: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (QUOTE_MSG, "IRQ"); + ptr->irq = val.num; + break; + case SCREEN: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "Screen"); + ptr->screen = val.num; + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintDeviceSection (FILE * cf, XConfigDevicePtr ptr) +{ + int i; + + while (ptr) + { + fprintf (cf, "Section \"Device\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + if (ptr->driver) + fprintf (cf, " Driver \"%s\"\n", ptr->driver); + if (ptr->vendor) + fprintf (cf, " VendorName \"%s\"\n", ptr->vendor); + if (ptr->board) + fprintf (cf, " BoardName \"%s\"\n", ptr->board); + if (ptr->chipset) + fprintf (cf, " ChipSet \"%s\"\n", ptr->chipset); + if (ptr->card) + fprintf (cf, " Card \"%s\"\n", ptr->card); + if (ptr->ramdac) + fprintf (cf, " RamDac \"%s\"\n", ptr->ramdac); + if (ptr->dacSpeeds[0] > 0 ) { + fprintf (cf, " DacSpeed "); + for (i = 0; i < CONF_MAXDACSPEEDS + && ptr->dacSpeeds[i] > 0; i++ ) + fprintf (cf, "%g ", (double) (ptr->dacSpeeds[i])/ 1000.0 ); + fprintf (cf, "\n"); + } + if (ptr->videoram) + fprintf (cf, " VideoRam %d\n", ptr->videoram); + if (ptr->bios_base) + fprintf (cf, " BiosBase 0x%lx\n", ptr->bios_base); + if (ptr->mem_base) + fprintf (cf, " MemBase 0x%lx\n", ptr->mem_base); + if (ptr->io_base) + fprintf (cf, " IOBase 0x%lx\n", ptr->io_base); + if (ptr->clockchip) + fprintf (cf, " ClockChip \"%s\"\n", ptr->clockchip); + if (ptr->chipid != -1) + fprintf (cf, " ChipId 0x%x\n", ptr->chipid); + if (ptr->chiprev != -1) + fprintf (cf, " ChipRev 0x%x\n", ptr->chiprev); + + xconfigPrintOptionList(cf, ptr->options, 1); + if (ptr->clocks > 0 ) { + fprintf (cf, " Clocks "); + for (i = 0; i < ptr->clocks; i++ ) + fprintf (cf, "%.1f ", (double)ptr->clock[i] / 1000.0 ); + fprintf (cf, "\n"); + } + if (ptr->textclockfreq) { + fprintf (cf, " TextClockFreq %.1f\n", + (double)ptr->textclockfreq / 1000.0); + } + if (ptr->busid) + fprintf (cf, " BusID \"%s\"\n", ptr->busid); + if (ptr->screen > -1) + fprintf (cf, " Screen %d\n", ptr->screen); + if (ptr->irq >= 0) + fprintf (cf, " IRQ %d\n", ptr->irq); + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigFreeDeviceList (XConfigDevicePtr *ptr) +{ + XConfigDevicePtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->vendor); + TEST_FREE ((*ptr)->board); + TEST_FREE ((*ptr)->chipset); + TEST_FREE ((*ptr)->card); + TEST_FREE ((*ptr)->driver); + TEST_FREE ((*ptr)->ramdac); + TEST_FREE ((*ptr)->clockchip); + TEST_FREE ((*ptr)->comment); + xconfigFreeOptionList (&((*ptr)->options)); + + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +int +xconfigValidateDevice (XConfigPtr p) +{ + XConfigDevicePtr device = p->devices; + + if (!device) { + xconfigErrorMsg(ValidationErrorMsg, "At least one Device section " + "is required."); + return (FALSE); + } + + while (device) { + if (!device->driver) { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_DRIVER_MSG, + device->identifier); + return (FALSE); + } + device = device->next; + } + return (TRUE); +} + +XConfigDevicePtr +xconfigFindDevice (const char *ident, XConfigDevicePtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + + +/* + * Determine what bus type the busID string represents. The start of the + * bus-dependent part of the string is returned as retID. + */ + +static int isPci(const char* busID, const char **retID) +{ + char *p, *s; + int ret = FALSE; + + /* If no type field, Default to PCI */ + if (isdigit(busID[0])) { + if (retID) + *retID = busID; + return TRUE; + } + + s = strdup(busID); + p = strtok(s, ":"); + if (p == NULL || *p == 0) { + free(s); + return FALSE; + } + if (!xconfigNameCompare(p, "pci") || !xconfigNameCompare(p, "agp")) { + if (retID) + *retID = busID + strlen(p) + 1; + ret = TRUE; + } + free(s); + return ret; +} + + +/* + * Parse a BUS ID string, and return the PCI bus parameters if it was + * in the correct format for a PCI bus id. + */ + +int xconfigParsePciBusString(const char *busID, + int *bus, int *device, int *func) +{ + /* + * The format is assumed to be "bus[@domain]:device[:func]", where domain, + * bus, device and func are decimal integers. func may be omitted and + * assumed to be zero. + */ + + char *p, *s, *d; + const char *id; + int i; + + if (!isPci(busID, &id)) + return FALSE; + + s = strdup(id); + p = strtok(s, ":"); + if (p == NULL || *p == 0) { + free(s); + return FALSE; + } + d = strpbrk(p, "@"); + if (d != NULL) { + *(d++) = 0; + for (i = 0; d[i] != 0; i++) { + if (!isdigit(d[i])) { + free(s); + return FALSE; + } + } + } + for (i = 0; p[i] != 0; i++) { + if (!isdigit(p[i])) { + free(s); + return FALSE; + } + } + *bus = atoi(p); + if (d != NULL && *d != 0) + *bus += atoi(d) << 8; + p = strtok(NULL, ":"); + if (p == NULL || *p == 0) { + free(s); + return FALSE; + } + for (i = 0; p[i] != 0; i++) { + if (!isdigit(p[i])) { + free(s); + return FALSE; + } + } + *device = atoi(p); + *func = 0; + p = strtok(NULL, ":"); + if (p == NULL || *p == 0) { + free(s); + return TRUE; + } + for (i = 0; p[i] != 0; i++) { + if (!isdigit(p[i])) { + free(s); + return FALSE; + } + } + *func = atoi(p); + free(s); + return TRUE; +} + + +/* + * xconfigFormatPciBusString : The function checks for the availability + * of PCI domain & accordingly formats the busid string. + */ +void xconfigFormatPciBusString(char *str, int len, + int domain, int bus, int device, int func) +{ + if (domain) { + snprintf(str, len, "PCI:%d@%d:%d:%d", bus, domain, device, func); + } else { + snprintf(str, len, "PCI:%d:%d:%d", bus, device, func); + } + str[len - 1] = '\0'; +} + + +/* + * xconfigAddInactiveDevice() - add a device to the inactive section of + * the xconfig layout. + */ +void xconfigAddInactiveDevice(XConfigPtr config, XConfigLayoutPtr layout, + int device_n) +{ + XConfigDevicePtr device; + XConfigInactivePtr inac; + + device = add_device(config, -1, -1, -1, NULL, device_n, + "modesetting", "Unknown", FALSE /* active */); + + inac = xconfigAlloc(sizeof (XConfigInactiveRec)); + inac->next = NULL; + inac->device = device; + inac->device_name = xconfigStrdup(device->identifier); + xconfigAddListItem((GenericListPtr *)(&layout->inactives), + (GenericListPtr) inac); +} /* xconfigAddInactiveDevice() */ + diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Extensions.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Extensions.c new file mode 100644 index 0000000..415ae17 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Extensions.c @@ -0,0 +1,103 @@ +/* + * Copyright 2004 Red Hat Inc., Raleigh, North Carolina. + * + * 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 on 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 (including the + * next paragraph) 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 + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * 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. + */ + +/* + * Authors: + * Kevin E. Martin + * + */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec ExtensionsTab[] = +{ + {ENDSECTION, "endsection"}, + {OPTION, "option"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeExtensions + +XConfigExtensionsPtr +xconfigParseExtensionsSection (void) +{ + int token; + + PARSE_PROLOGUE (XConfigExtensionsPtr, XConfigExtensionsRec); + + while ((token = xconfigGetToken (ExtensionsTab)) != ENDSECTION) { + switch (token) { + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintExtensionsSection (FILE * cf, XConfigExtensionsPtr ptr) +{ + XConfigOptionPtr p; + + if (ptr == NULL || ptr->options == NULL) + return; + + p = ptr->options; + fprintf (cf, "Section \"Extensions\"\n"); + if (ptr->comment) fprintf (cf, "%s", ptr->comment); + xconfigPrintOptionList(cf, p, 1); + fprintf (cf, "EndSection\n\n"); +} + +void +xconfigFreeExtensions (XConfigExtensionsPtr *ptr) +{ + if (ptr == NULL || *ptr == NULL) + return; + + xconfigFreeOptionList (&((*ptr)->options)); + TEST_FREE ((*ptr)->comment); + free (*ptr); + *ptr = NULL; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Files.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Files.c new file mode 100644 index 0000000..dac9335 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Files.c @@ -0,0 +1,282 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec FilesTab[] = +{ + {ENDSECTION, "endsection"}, + {FONTPATH, "fontpath"}, + {RGBPATH, "rgbpath"}, + {MODULEPATH, "modulepath"}, + {INPUTDEVICES, "inputdevices"}, + {LOGFILEPATH, "logfile"}, + {-1, ""}, +}; + +static char * +prependRoot (char *pathname) +{ + return pathname; +} + +#define CLEANUP xconfigFreeFiles + +XConfigFilesPtr +xconfigParseFilesSection (void) +{ + int i, j; + int k, l; + char *str; + int token; + PARSE_PROLOGUE (XConfigFilesPtr, XConfigFilesRec) + + while ((token = xconfigGetToken (FilesTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case FONTPATH: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "FontPath"); + j = FALSE; + str = prependRoot (val.str); + if (ptr->fontpath == NULL) + { + ptr->fontpath = malloc (1); + ptr->fontpath[0] = '\0'; + i = strlen (str) + 1; + } + else + { + i = strlen (ptr->fontpath) + strlen (str) + 1; + if (ptr->fontpath[strlen (ptr->fontpath) - 1] != ',') + { + i++; + j = TRUE; + } + } + ptr->fontpath = realloc (ptr->fontpath, i); + if (j) + strcat (ptr->fontpath, ","); + + strcat (ptr->fontpath, str); + free (val.str); + break; + case RGBPATH: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "RGBPath"); + ptr->rgbpath = val.str; + break; + case MODULEPATH: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "ModulePath"); + l = FALSE; + str = prependRoot (val.str); + if (ptr->modulepath == NULL) + { + ptr->modulepath = malloc (1); + ptr->modulepath[0] = '\0'; + k = strlen (str) + 1; + } + else + { + k = strlen (ptr->modulepath) + strlen (str) + 1; + if (ptr->modulepath[strlen (ptr->modulepath) - 1] != ',') + { + k++; + l = TRUE; + } + } + ptr->modulepath = realloc (ptr->modulepath, k); + if (l) + strcat (ptr->modulepath, ","); + + strcat (ptr->modulepath, str); + free (val.str); + break; + case INPUTDEVICES: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "InputDevices"); + l = FALSE; + str = prependRoot (val.str); + if (ptr->inputdevs == NULL) + { + ptr->inputdevs = malloc (1); + ptr->inputdevs[0] = '\0'; + k = strlen (str) + 1; + } + else + { + k = strlen (ptr->inputdevs) + strlen (str) + 1; + if (ptr->inputdevs[strlen (ptr->inputdevs) - 1] != ',') + { + k++; + l = TRUE; + } + } + ptr->inputdevs = realloc (ptr->inputdevs, k); + if (l) + strcat (ptr->inputdevs, ","); + + strcat (ptr->inputdevs, str); + free (val.str); + break; + case LOGFILEPATH: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "LogFile"); + ptr->logfile = val.str; + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintFileSection (FILE * cf, XConfigFilesPtr ptr) +{ + char *p, *s; + + if (ptr == NULL) + return; + + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->logfile) + fprintf (cf, " LogFile \"%s\"\n", ptr->logfile); + if (ptr->rgbpath) + fprintf (cf, " RgbPath \"%s\"\n", ptr->rgbpath); + if (ptr->modulepath) + { + s = ptr->modulepath; + p = index (s, ','); + while (p) + { + *p = '\000'; + fprintf (cf, " ModulePath \"%s\"\n", s); + *p = ','; + s = p; + s++; + p = index (s, ','); + } + fprintf (cf, " ModulePath \"%s\"\n", s); + } + if (ptr->inputdevs) + { + s = ptr->inputdevs; + p = index (s, ','); + while (p) + { + *p = '\000'; + fprintf (cf, " InputDevices \"%s\"\n", s); + *p = ','; + s = p; + s++; + p = index (s, ','); + } + fprintf (cf, " InputDevices \"%s\"\n", s); + } + if (ptr->fontpath) + { + s = ptr->fontpath; + p = index (s, ','); + while (p) + { + *p = '\000'; + fprintf (cf, " FontPath \"%s\"\n", s); + *p = ','; + s = p; + s++; + p = index (s, ','); + } + fprintf (cf, " FontPath \"%s\"\n", s); + } +} + +void +xconfigFreeFiles (XConfigFilesPtr *p) +{ + if (p == NULL || *p == NULL) + return; + + TEST_FREE ((*p)->logfile); + TEST_FREE ((*p)->rgbpath); + TEST_FREE ((*p)->modulepath); + TEST_FREE ((*p)->inputdevs); + TEST_FREE ((*p)->fontpath); + TEST_FREE ((*p)->comment); + + free (*p); + *p = NULL; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Flags.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Flags.c new file mode 100644 index 0000000..cfbff5e --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Flags.c @@ -0,0 +1,582 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" +#include +#include "common-utils.h" + +extern LexRec val; + +static XConfigSymTabRec ServerFlagsTab[] = +{ + {ENDSECTION, "endsection"}, + {NOTRAPSIGNALS, "notrapsignals"}, + {DONTZAP, "dontzap"}, + {DONTZOOM, "dontzoom"}, + {DISABLEVIDMODE, "disablevidmodeextension"}, + {ALLOWNONLOCAL, "allownonlocalxvidtune"}, + {DISABLEMODINDEV, "disablemodindev"}, + {MODINDEVALLOWNONLOCAL, "allownonlocalmodindev"}, + {ALLOWMOUSEOPENFAIL, "allowmouseopenfail"}, + {OPTION, "option"}, + {BLANKTIME, "blanktime"}, + {STANDBYTIME, "standbytime"}, + {SUSPENDTIME, "suspendtime"}, + {OFFTIME, "offtime"}, + {DEFAULTLAYOUT, "defaultserverlayout"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeFlags + +XConfigFlagsPtr +xconfigParseFlagsSection (void) +{ + int token; + PARSE_PROLOGUE (XConfigFlagsPtr, XConfigFlagsRec) + + while ((token = xconfigGetToken (ServerFlagsTab)) != ENDSECTION) + { + int hasvalue = FALSE; + int strvalue = FALSE; + int tokentype; + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + /* + * these old keywords are turned into standard generic options. + * we fall through here on purpose + */ + case DEFAULTLAYOUT: + strvalue = TRUE; + /* fall through */ + case BLANKTIME: + case STANDBYTIME: + case SUSPENDTIME: + case OFFTIME: + hasvalue = TRUE; + /* fall through */ + case NOTRAPSIGNALS: + case DONTZAP: + case DONTZOOM: + case DISABLEVIDMODE: + case ALLOWNONLOCAL: + case DISABLEMODINDEV: + case MODINDEVALLOWNONLOCAL: + case ALLOWMOUSEOPENFAIL: + { + int i = 0; + while (ServerFlagsTab[i].token != -1) + { + if (ServerFlagsTab[i].token == token) + { + char buff[16]; + char *valstr = NULL; + if (hasvalue) + { + tokentype = xconfigGetSubToken(&(ptr->comment)); + if (strvalue) { + if (tokentype != STRING) + Error (QUOTE_MSG, ServerFlagsTab[i].name); + valstr = val.str; + } else { + if (tokentype != NUMBER) + Error (NUMBER_MSG, ServerFlagsTab[i].name); + snprintf(buff, 16, "%d", val.num); + valstr = buff; + } + } + xconfigAddNewOption(&ptr->options, + ServerFlagsTab[i].name, valstr); + } + i++; + } + } + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintServerFlagsSection (FILE * f, XConfigFlagsPtr flags) +{ + XConfigOptionPtr p; + + if ((!flags) || (!flags->options)) + return; + p = flags->options; + fprintf (f, "Section \"ServerFlags\"\n"); + if (flags->comment) + fprintf (f, "%s", flags->comment); + xconfigPrintOptionList(f, p, 1); + fprintf (f, "EndSection\n\n"); +} + +void +xconfigAddNewOption (XConfigOptionPtr *pHead, const char *name, + const char *val) +{ + XConfigOptionPtr new; + XConfigOptionPtr old = NULL; + + /* Don't allow duplicates */ + if (*pHead != NULL && + ((old = xconfigFindOption(*pHead, name)) != NULL)) { + TEST_FREE(old->name); + TEST_FREE(old->val); + new = old; + } else { + new = calloc(1, sizeof (XConfigOptionRec)); + new->next = NULL; + } + new->name = xconfigStrdup(name); + new->val = xconfigStrdup(val); + + if (old == NULL) { + xconfigAddListItem((GenericListPtr *)(pHead), (GenericListPtr)new); + } +} + +void +xconfigFreeFlags (XConfigFlagsPtr *flags) +{ + if (flags == NULL || *flags == NULL) + return; + + xconfigFreeOptionList (&((*flags)->options)); + TEST_FREE((*flags)->comment); + free (*flags); + *flags = NULL; +} + +XConfigOptionPtr +xconfigOptionListDup (XConfigOptionPtr opt) +{ + XConfigOptionPtr newopt = NULL; + + while (opt) { + xconfigAddNewOption(&newopt, opt->name, opt->val); + if (newopt) { + newopt->comment = xconfigStrdup(opt->comment); + } + opt = opt->next; + } + return newopt; +} + +void +xconfigFreeOptionList (XConfigOptionPtr *opt) +{ + XConfigOptionPtr prev; + + if (opt == NULL || *opt == NULL) + return; + + while (*opt) + { + TEST_FREE ((*opt)->name); + TEST_FREE ((*opt)->val); + TEST_FREE ((*opt)->comment); + prev = *opt; + *opt = (*opt)->next; + free (prev); + } +} + +char * +xconfigOptionName(XConfigOptionPtr opt) +{ + if (opt) + return opt->name; + return 0; +} + +char * +xconfigOptionValue(XConfigOptionPtr opt) +{ + if (opt) + return opt->val; + return 0; +} + +XConfigOptionPtr +xconfigNewOption(const char *name, const char *value) +{ + XConfigOptionPtr opt; + + opt = calloc(1, sizeof (XConfigOptionRec)); + if (!opt) + return NULL; + + opt->name = xconfigStrdup(name); + opt->val = xconfigStrdup(value); + opt->next = NULL; + + return opt; +} + +void +xconfigRemoveOption(XConfigOptionPtr *pHead, XConfigOptionPtr opt) +{ + xconfigRemoveListItem((GenericListPtr *)pHead, (GenericListPtr)opt); + + TEST_FREE(opt->name); + TEST_FREE(opt->val); + TEST_FREE(opt->comment); + free(opt); +} + +XConfigOptionPtr +xconfigNextOption(XConfigOptionPtr list) +{ + if (!list) + return NULL; + return list->next; +} + +/* + * this function searches the given option list for the named option and + * returns a pointer to the option rec if found. If not found, it returns + * NULL + */ + +XConfigOptionPtr +xconfigFindOption (XConfigOptionPtr list, const char *name) +{ + while (list) + { + if (xconfigNameCompare (list->name, name) == 0) + return (list); + list = list->next; + } + return (NULL); +} + +/* + * this function searches the given option list for the named option. If + * found and the option has a parameter, a pointer to the parameter is + * returned. If the option does not have a parameter an empty string is + * returned. If the option is not found, a NULL is returned. + */ + +char * +xconfigFindOptionValue (XConfigOptionPtr list, const char *name) +{ + XConfigOptionPtr p = xconfigFindOption (list, name); + + if (p) + { + if (p->val) + return (p->val); + else + return ""; + } + return (NULL); +} + +/* + * this function searches the given option list for the named option. If + * found and the the value of the option is set to "1", "ON", "YES" or + * "TRUE", 1 is returned. Otherwise, 0 is returned. + */ + +int +xconfigFindOptionBoolean (XConfigOptionPtr list, const char *name) +{ + XConfigOptionPtr p = xconfigFindOption (list, name); + + if (p && p->val) + { + if ( strcasecmp(p->val, "1") == 0 || + strcasecmp(p->val, "ON") == 0 || + strcasecmp(p->val, "YES") == 0 || + strcasecmp(p->val, "TRUE") == 0 ) + { + return 1; + } + } + return 0; +} + +/* the 2 given lists are merged. If an option with the same name is present in + * both, the option from the user list - specified in the second argument - + * is used. The end result is a single valid list of options. Duplicates + * are freed, and the original lists are no longer guaranteed to be complete. + */ +XConfigOptionPtr +xconfigOptionListMerge (XConfigOptionPtr head, XConfigOptionPtr tail) +{ + XConfigOptionPtr a, b, ap = NULL, bp = NULL; + + a = tail; + b = head; + while (tail && b) { + if (xconfigNameCompare (a->name, b->name) == 0) { + if (b == head) + head = a; + else + bp->next = a; + if (a == tail) + tail = a->next; + else + ap->next = a->next; + a->next = b->next; + b->next = NULL; + xconfigFreeOptionList (&b); + b = a->next; + bp = a; + a = tail; + ap = NULL; + } else { + ap = a; + if (!(a = a->next)) { + a = tail; + bp = b; + b = b->next; + ap = NULL; + } + } + } + + if (head) { + for (a = head; a->next; a = a->next) + ; + a->next = tail; + } else + head = tail; + + return (head); +} + +char * +xconfigULongToString(unsigned long i) +{ + char *s; + int l; + + l = (int)(ceil(log10((double)i) + 2.5)); + s = malloc(l); + if (!s) + return NULL; + sprintf(s, "%lu", i); + return s; +} + +XConfigOptionPtr +xconfigParseOption(XConfigOptionPtr head) +{ + XConfigOptionPtr option, cnew, old; + char *name, *comment = NULL; + int token; + + if ((token = xconfigGetSubToken(&comment)) != STRING) { + xconfigErrorMsg(ParseErrorMsg, BAD_OPTION_MSG); + if (comment) + free(comment); + return (head); + } + + name = val.str; + if ((token = xconfigGetSubToken(&comment)) == STRING) { + option = xconfigNewOption(name, val.str); + option->comment = comment; + if ((token = xconfigGetToken(NULL)) == COMMENT) + option->comment = xconfigAddComment(option->comment, val.str); + else + xconfigUnGetToken(token); + } + else { + option = xconfigNewOption(name, NULL); + option->comment = comment; + if (token == COMMENT) + option->comment = xconfigAddComment(option->comment, val.str); + else + xconfigUnGetToken(token); + } + + old = NULL; + + /* Don't allow duplicates */ + if (head != NULL && (old = xconfigFindOption(head, name)) != NULL) { + cnew = old; + free(option->name); + TEST_FREE(option->val); + TEST_FREE(option->comment); + free(option); + } + else + cnew = option; + + if (old == NULL) { + xconfigAddListItem((GenericListPtr *)(&head), (GenericListPtr)cnew); + } + + return head; +} + +void +xconfigPrintOptionList(FILE *fp, XConfigOptionPtr list, int tabs) +{ + int i; + + if (!list) + return; + while (list) { + for (i = 0; i < tabs; i++) + fprintf(fp, " "); + if (list->val) + fprintf(fp, "Option \"%s\" \"%s\"", list->name, list->val); + else + fprintf(fp, "Option \"%s\"", list->name); + if (list->comment) + fprintf(fp, "%s", list->comment); + else + fputc('\n', fp); + list = list->next; + } +} + +/* + * Determines if the Composite extension should be disabled or not. + * + * - If the extension can be enabled, this function returns NULL. + * + * - If the extension should be disabled, this function returns a + * string that lists the conflicting options that are enabled. The string + * returned has to be freed by the caller. + */ + +char *xconfigValidateComposite(XConfigPtr config, + GenerateOptions *gop, + int composite_specified, + int xinerama_enabled, + int depth, + int overlay_enabled, + int cioverlay_enabled, + int ubb_enabled, + int stereo_enabled) +{ + int i, n; + char *err_str; + + const struct { + const char *name; + int value; + + } composite_incompatible_options[] = { + { "Xinerama", xinerama_enabled && !gop->xinerama_plus_composite_works }, + { "Overlay", overlay_enabled }, + { "CIOverlay", cioverlay_enabled }, + }; + + /* + * We need to be careful to only set the option value if the X + * server is going to recognize the Extension section and the + * composite option. We guess whether the server will recognize + * the option: if get_xserver_in_use() thinks the X server + * supports the "Composite" extension, or the current config + * already has an extension section, or the user specified the + * composite option. + */ + if (!gop->supports_extension_section && + !config->extensions && + !composite_specified) { + /* Composite can't be set in X config, so bail */ + return NULL; + } + + n = 0; + err_str = NULL; + + for (i = 0; i < ARRAY_LEN(composite_incompatible_options); i++) { + int value = composite_incompatible_options[i].value; + const char *name = composite_incompatible_options[i].name; + + if (value) { + err_str = nv_prepend_to_string_list(err_str, name, + (n > 1) ? ", " : " or "); + n++; + } + } + + /* Special case checking for depth 8 */ + + if (depth <= 8) { + err_str = nv_prepend_to_string_list(err_str, "depth=8", + (n > 1) ? ", " : " or "); + } + + return err_str; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Generate.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Generate.c new file mode 100644 index 0000000..34eb0d4 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Generate.c @@ -0,0 +1,1491 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2005 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * Generate.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xf86Parser.h" +#include "Configint.h" + +#define MOUSE_IDENTIFER "Mouse0" +#define KEYBOARD_IDENTIFER "Keyboard0" + +#define SCREEN_IDENTIFIER "Screen%d" +#define DEVICE_IDENTIFIER "%sDevice%d" +#define MONITOR_IDENTIFIER "Monitor%d" + + +static int is_file(const char *filename); + +static void add_font_path(GenerateOptions *gop, XConfigPtr config); +static void add_modules(GenerateOptions *gop, XConfigPtr config); + +static void add_layout(GenerateOptions *gop, XConfigPtr config); + +static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout, + char *name, char *coreKeyword); + +/* + * xconfigGenerate() - generate a new XConfig from scratch + */ + +XConfigPtr xconfigGenerate(GenerateOptions *gop) +{ + XConfigPtr config; + + config = xconfigAlloc(sizeof(XConfigRec)); + + /* add files, fonts, and modules */ + + config->files = xconfigAlloc(sizeof(XConfigFilesRec)); + add_font_path(gop, config); + add_modules(gop, config); + + /* add the keyboard and mouse */ + + xconfigAddKeyboard(gop, config); + xconfigAddMouse(gop, config); + + /* add the layout */ + + add_layout(gop, config); + + return config; + +} /* xconfigGenerate() */ + + + +/* + * xconfigGenerateAddScreen() - add a new screen to the config; bus + * and slot can be -1 to be ignored; boardname can be NULL to be + * ignored; count is used when building the identifier name, eg + * '"Screen%d", count'. Note that this does not append the screen to + * any layout's adjacency list. + */ + +XConfigScreenPtr xconfigGenerateAddScreen(XConfigPtr config, + int bus, int domain, int slot, + char *boardname, int count, + const char *driver, + const char *vendor) +{ + XConfigScreenPtr screen, s; + XConfigDevicePtr device; + XConfigMonitorPtr monitor; + + monitor = xconfigAddMonitor(config, count); + device = add_device(config, bus, domain, slot, boardname, count, + driver, vendor, TRUE /* active */); + + screen = xconfigAlloc(sizeof(XConfigScreenRec)); + + screen->identifier = xconfigAlloc(32); + snprintf(screen->identifier, 32, SCREEN_IDENTIFIER, count); + + screen->device_name = xconfigStrdup(device->identifier); + screen->device = device; + + screen->monitor_name = xconfigStrdup(monitor->identifier); + screen->monitor = monitor; + + screen->defaultdepth = 24; + + xconfigAddDisplay(&screen->displays, screen->defaultdepth); + + /* append to the end of the screen list */ + + if (!config->screens) { + config->screens = screen; + } else { + for (s = config->screens; s->next; s = s->next); + s->next = screen; + } + + return screen; + +} /* xconfigGenerateAddScreen() */ + + + +/* + * xconfigGenerateAssignScreenAdjacencies() - setup all the adjacency + * information for the X screens in the given layout. Nothing fancy + * here: just position all the screens horizontally, moving from left + * to right. + */ + +void xconfigGenerateAssignScreenAdjacencies(XConfigLayoutPtr layout) +{ + XConfigAdjacencyPtr adj, prev = NULL; + + for (adj = layout->adjacencies; adj; adj = adj->next) { + + if (prev) { + adj->where = CONF_ADJ_RIGHTOF; + adj->refscreen = xconfigStrdup(prev->screen_name); + } else { + adj->x = adj->y = -1; + } + + /* make sure all the obsolete positioning is empty */ + + adj->top = NULL; + adj->top_name = NULL; + adj->bottom = NULL; + adj->bottom_name = NULL; + adj->left = NULL; + adj->left_name = NULL; + adj->right = NULL; + adj->right_name = NULL; + + prev = adj; + } + +} /* xconfigGenerateAssignScreenAdjacencies() */ + + + +/*********************************************************************/ + + + +/* + * is_file() + */ + +static int is_file(const char *filename) +{ + return (access(filename, F_OK) == 0); + +} /* is_file() */ + + +/* + * find_libdir() - attempt to find the X server library path; this is + * either + * + * `pkg-config --variable=libdir xorg-server` + * + * or + * + * [X PROJECT ROOT]/lib + */ + +static char *find_libdir(GenerateOptions *gop) +{ + struct stat stat_buf; + FILE *stream = NULL; + char *s, *libdir = NULL; + + /* + * run the pkg-config command and read the output; if the output + * is a directory, then return that as the libdir + */ + + stream = popen("pkg-config --variable=libdir xorg-server", "r"); + + if (stream) { + char buf[256]; + + buf[0] = '\0'; + + while (1) { + if (fgets(buf, 255, stream) == NULL) break; + + if (buf[0] != '\0') { + + /* truncate any newline */ + + s = strchr(buf, '\n'); + if (s) *s = '\0'; + + if ((stat(buf, &stat_buf) == 0) && + (S_ISDIR(stat_buf.st_mode))) { + + libdir = xconfigStrdup(buf); + break; + } + } + } + + pclose(stream); + + if (libdir) return libdir; + } + + /* otherwise, just fallback to [X PROJECT ROOT]/lib */ + + return xconfigStrcat(gop->x_project_root, "/lib", NULL); + +} /* find_libdir() */ + + + +/* + * add_font_path() - scan through the __font_paths[] array, + * temporarily chop off the ":unscaled" appendage, and check for the + * file "fonts.dir" in the directory. If fonts.dir exists, append the + * path to config->files->fontpath. + */ + +static void add_font_path(GenerateOptions *gop, XConfigPtr config) +{ + int i, ret; + char *path, *p, *orig, *fonts_dir, *libdir; + + /* + * The below font path has been constructed from various examples + * and uses some suggests from the Font De-uglification HOWTO + */ + + static const char *__font_paths[] = { + "LIBDIR/X11/fonts/local/", + "LIBDIR/X11/fonts/misc/:unscaled", + "LIBDIR/X11/fonts/100dpi/:unscaled", + "LIBDIR/X11/fonts/75dpi/:unscaled", + "LIBDIR/X11/fonts/misc/", + "LIBDIR/X11/fonts/Type1/", + "LIBDIR/X11/fonts/CID/", + "LIBDIR/X11/fonts/Speedo/", + "LIBDIR/X11/fonts/100dpi/", + "LIBDIR/X11/fonts/75dpi/", + "LIBDIR/X11/fonts/cyrillic/", + "LIBDIR/X11/fonts/TTF/", + "LIBDIR/X11/fonts/truetype/", + "LIBDIR/X11/fonts/TrueType/", + "LIBDIR/X11/fonts/Type1/sun/", + "LIBDIR/X11/fonts/F3bitmaps/", + "/usr/local/share/fonts/ttfonts", + "/usr/share/fonts/default/Type1", + "/usr/lib/openoffice/share/fonts/truetype", + NULL + }; + + /* + * if a font server is running, set the font path to that + * + * XXX should we check the port the font server is using? + */ +#if defined(NV_SUNOS) + ret = system("ps -e -o fname | grep -v grep | egrep \"^xfs$\" > /dev/null"); +#elif defined(NV_BSD) + ret = system("ps -e -o comm | grep -v grep | egrep \"^xfs$\" > /dev/null"); +#else + ret = system("ps -C xfs 2>&1 > /dev/null"); +#endif + if (WEXITSTATUS(ret) == 0) { + config->files->fontpath = xconfigStrdup("unix/:7100"); + } else { + + /* get the X server libdir */ + + libdir = find_libdir(gop); + + for (i = 0; __font_paths[i]; i++) { + path = xconfigStrdup(__font_paths[i]); + + /* replace LIBDIR with libdir */ + + if (strncmp(path, "LIBDIR", 6) == 0) { + p = xconfigStrcat(libdir, path + 6, NULL); + free(path); + path = p; + } + + /* temporarily chop off any ":unscaled" appendage */ + + p = strchr(path, ':'); + if (p) *p = '\0'; + + /* skip this entry if the fonts.dir does not exist */ + + fonts_dir = xconfigStrcat(path, "/fonts.dir", NULL); + if (!is_file(fonts_dir)) { + /* does not exist */ + free(path); + free(fonts_dir); + continue; + } + free(fonts_dir); + + /* add the ":unscaled" back */ + + if (p) *p = ':'; + + /* + * either use this path as the fontpath, or append to the + * existing fontpath + */ + + if (config->files->fontpath) { + orig = config->files->fontpath; + config->files->fontpath = xconfigStrcat(orig, ",", path, NULL); + free(orig); + free(path); + } else { + config->files->fontpath = path; + } + } + + /* free the libdir string */ + + free(libdir); + } +} /* add_font_path() */ + + + +/* + * add_modules() + */ + +static void add_modules(GenerateOptions *gop, XConfigPtr config) +{ + XConfigLoadPtr l = NULL; + + /* + * if the X server will automatically autoload GLX, then don't + * bother adding a modules section; it is difficult for + * nvidia-xconfig to know if modules like "type1" are present, + * anyway. + */ + + if (gop->autoloads_glx) return; + + config->modules = xconfigAlloc(sizeof(XConfigModuleRec)); + + xconfigAddNewLoadDirective(&l, xconfigStrdup("dbe"), + XCONFIG_LOAD_MODULE, NULL, FALSE); + xconfigAddNewLoadDirective(&l, xconfigStrdup("extmod"), + XCONFIG_LOAD_MODULE, NULL, FALSE); + xconfigAddNewLoadDirective(&l, xconfigStrdup("type1"), + XCONFIG_LOAD_MODULE, NULL, FALSE); +#if defined(NV_SUNOS) + xconfigAddNewLoadDirective(&l, xconfigStrdup("IA"), + XCONFIG_LOAD_MODULE, NULL, FALSE); + xconfigAddNewLoadDirective(&l, xconfigStrdup("bitstream"), + XCONFIG_LOAD_MODULE, NULL, FALSE); + xconfigAddNewLoadDirective(&l, xconfigStrdup("xtsol"), + XCONFIG_LOAD_MODULE, NULL, FALSE); +#else + xconfigAddNewLoadDirective(&l, xconfigStrdup("freetype"), + XCONFIG_LOAD_MODULE, NULL, FALSE); +#endif + xconfigAddNewLoadDirective(&l, xconfigStrdup("glx"), + XCONFIG_LOAD_MODULE, NULL, FALSE); + + config->modules->loads = l; + +} /* add_modules() */ + + + +/* + * xconfigAddMonitor() - + * + * XXX pass EDID values into this... + */ + +XConfigMonitorPtr xconfigAddMonitor(XConfigPtr config, int count) +{ + XConfigMonitorPtr monitor, m; + + /* XXX need to query resman for the EDID */ + + monitor = xconfigAlloc(sizeof(XConfigMonitorRec)); + + monitor->identifier = xconfigAlloc(32); + snprintf(monitor->identifier, 32, MONITOR_IDENTIFIER, count); + monitor->vendor = xconfigStrdup("Unknown"); /* XXX */ + monitor->modelname = xconfigStrdup("Unknown"); /* XXX */ + + monitor->options = NULL; + xconfigAddNewOption(&monitor->options, "DPMS", NULL); + + /* append to the end of the monitor list */ + + if (!config->monitors) { + config->monitors = monitor; + } else { + for (m = config->monitors; m->next; m = m->next); + m->next = monitor; + } + + return monitor; + +} /* xconfigAddMonitor() */ + + + +/* + * add_device() + */ + +XConfigDevicePtr add_device(XConfigPtr config, int bus, int domain, + int slot, char *boardname, int count, + const char *driver, const char *vendor, int active) +{ + XConfigDevicePtr device, d; + + device = xconfigAlloc(sizeof(XConfigDeviceRec)); + + device->identifier = xconfigAlloc(32); + snprintf(device->identifier, 32, DEVICE_IDENTIFIER, + active ? "" : "Inactive", count); + device->index_id = count; + device->driver = xconfigStrdup(driver); + device->vendor = xconfigStrdup(vendor); + + if (bus != -1 && domain != -1 && slot != -1) { + device->busid = xconfigAlloc(32); + xconfigFormatPciBusString(device->busid, 32, domain, bus, slot, 0); + } + + if (boardname) device->board = xconfigStrdup(boardname); + + device->chipid = -1; + device->chiprev = -1; + device->irq = -1; + device->screen = -1; + + /* append to the end of the device list */ + + if (!config->devices) { + config->devices = device; + } else { + for (d = config->devices; d->next; d = d->next); + d->next = device; + } + + return device; + +} /* add_device() */ + + + +void xconfigAddDisplay(XConfigDisplayPtr *pHead, const int depth) +{ + XConfigDisplayPtr display; + + display = xconfigAlloc(sizeof(XConfigDisplayRec)); + display->depth = depth; + display->modes = NULL; + display->frameX0 = -1; + display->frameY0 = -1; + display->black.red = -1; + display->white.red = -1; + + display->next = *pHead; + *pHead = display; +} + + + +/* + * add_layout() - add a layout section to the XConfigPtr + */ + +static void add_layout(GenerateOptions *gop, XConfigPtr config) +{ + XConfigLayoutPtr layout; + XConfigAdjacencyPtr adj; + XConfigScreenPtr screen; + + /* assume 1 X screen */ + + screen = xconfigGenerateAddScreen(config, -1, -1, -1, NULL, 0, + "nvidia", "NVIDIA Corporation"); + + /* create layout */ + + layout = xconfigAlloc(sizeof(XConfigLayoutRec)); + + layout->identifier = xconfigStrdup("Layout0"); + + adj = xconfigAlloc(sizeof(XConfigAdjacencyRec)); + + adj->scrnum = 0; + adj->screen = screen; + adj->screen_name = xconfigStrdup(screen->identifier); + + layout->adjacencies = adj; + + xconfigGenerateAssignScreenAdjacencies(layout); + + add_inputref(config, layout, MOUSE_IDENTIFER, "CorePointer"); + add_inputref(config, layout, KEYBOARD_IDENTIFER, "CoreKeyboard"); + + layout->next = config->layouts; + config->layouts = layout; + +} /* add_layout() */ + + + +/* + * add_inputref() - add a new XConfigInputrefPtr to the given layout + */ + +static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout, + char *name, char *coreKeyword) +{ + XConfigInputrefPtr inputRef; + + inputRef = xconfigAlloc(sizeof(XConfigInputrefRec)); + inputRef->input_name = xconfigStrdup(name); + inputRef->input = xconfigFindInput(inputRef->input_name, config->inputs); + inputRef->options = NULL; + xconfigAddNewOption(&inputRef->options, coreKeyword, NULL); + inputRef->next = layout->inputs; + layout->inputs = inputRef; + +} /* add_inputref() */ + + + +/*********************************************************************/ + +/* + * Mouse detection + */ + + +typedef struct { + char *shortname; /* commandline name */ + char *name; /* mouse name */ + char *gpmproto; /* protocol used by gpm */ + char *Xproto; /* XFree86 Protocol */ + char *device; /* /dev/ file */ + int emulate3; /* Emulate3Buttons */ +} MouseEntry; + + +/* + * This table is based on data contained in + * /usr/lib/python2.2/site-packages/rhpl/mouse.py on Red Hat Fedora + * core 1. That file contains the following copyright: + * + * + * mouse.py: mouse configuration data + * + * Copyright 1999-2002 Red Hat, Inc. + */ + +static const MouseEntry __mice[] = { + /* shortname name gpm protocol X protocol device emulate3 */ + { "alpsps/2", "ALPS - GlidePoint (PS/2)", "ps/2", "GlidePointPS/2", "psaux", TRUE }, + { "ascii", "ASCII - MieMouse (serial)", "ms3", "IntelliMouse", "ttyS", FALSE }, + { "asciips/2", "ASCII - MieMouse (PS/2)", "ps/2", "NetMousePS/2", "psaux", TRUE }, + { "atibm", "ATI - Bus Mouse", "Busmouse", "BusMouse", "atibm", TRUE }, + { "generic", "Generic - 2 Button Mouse (serial)", "Microsoft", "Microsoft", "ttyS", TRUE }, + { "generic3", "Generic - 3 Button Mouse (serial)", "Microsoft", "Microsoft", "ttyS", FALSE }, + { "genericps/2", "Generic - 2 Button Mouse (PS/2)", "ps/2", "PS/2", "psaux", TRUE }, + { "generic3ps/2", "Generic - 3 Button Mouse (PS/2)", "ps/2", "PS/2", "psaux", FALSE }, + { "genericwheelps/2", "Generic - Wheel Mouse (PS/2)", "imps2", "IMPS/2", "psaux", FALSE }, + { "genericusb", "Generic - 2 Button Mouse (USB)", "imps2", "IMPS/2", "input/mice", TRUE }, + { "generic3usb", "Generic - 3 Button Mouse (USB)", "imps2", "IMPS/2", "input/mice", FALSE }, + { "genericwheelusb", "Generic - Wheel Mouse (USB)", "imps2", "IMPS/2", "input/mice", FALSE }, + { "geniusnm", "Genius - NetMouse (serial)", "ms3", "IntelliMouse", "ttyS", TRUE }, + { "geniusnmps/2", "Genius - NetMouse (PS/2)", "netmouse", "NetMousePS/2", "psaux", TRUE }, + { "geniusprops/2", "Genius - NetMouse Pro (PS/2)", "netmouse", "NetMousePS/2", "psaux", TRUE }, + { "geniusscrollps/2", "Genius - NetScroll (PS/2)", "netmouse", "NetScrollPS/2", "psaux", TRUE }, + { "geniusscrollps/2+", "Genius - NetScroll+ (PS/2)", "netmouse", "NetMousePS/2", "psaux", FALSE }, + { "thinking", "Kensington - Thinking Mouse (serial)", "Microsoft", "ThinkingMouse", "ttyS", TRUE }, + { "thinkingps/2", "Kensington - Thinking Mouse (PS/2)", "ps/2", "ThinkingMousePS/2", "psaux", TRUE }, + { "logitech", "Logitech - C7 Mouse (serial, old C7 type)", "Logitech", "Logitech", "ttyS", FALSE }, + { "logitechcc", "Logitech - CC Series (serial)", "logim", "MouseMan", "ttyS", FALSE }, + { "logibm", "Logitech - Bus Mouse", "Busmouse", "BusMouse", "logibm", FALSE }, + { "logimman", "Logitech - MouseMan/FirstMouse (serial)", "MouseMan", "MouseMan", "ttyS", FALSE }, + { "logimmanps/2", "Logitech - MouseMan/FirstMouse (PS/2)", "ps/2", "PS/2", "psaux", FALSE }, + { "logimman+", "Logitech - MouseMan+/FirstMouse+ (serial)", "pnp", "IntelliMouse", "ttyS", FALSE }, + { "logimman+ps/2", "Logitech - MouseMan+/FirstMouse+ (PS/2)", "ps/2", "MouseManPlusPS/2", "psaux", FALSE }, + { "logimmusb", "Logitech - MouseMan Wheel (USB)", "ps/2", "IMPS/2", "input/mice", FALSE }, + { "logimmusboptical", "Logitech - Cordless Optical Mouse (USB)", "ps/2", "IMPS/2", "input/mice", FALSE }, + { "microsoft", "Microsoft - Compatible Mouse (serial)", "Microsoft", "Microsoft", "ttyS", TRUE }, + { "msnew", "Microsoft - Rev 2.1A or higher (serial)", "pnp", "Auto", "ttyS", TRUE }, + { "msintelli", "Microsoft - IntelliMouse (serial)", "ms3", "IntelliMouse", "ttyS", FALSE }, + { "msintellips/2", "Microsoft - IntelliMouse (PS/2)", "imps2", "IMPS/2", "psaux", FALSE }, + { "msintelliusb", "Microsoft - IntelliMouse (USB)", "ps/2", "IMPS/2", "input/mice", FALSE }, + { "msintelliusboptical","Microsoft - IntelliMouse Optical (USB)", "ps/2", "IMPS/2", "input/mice", FALSE }, + { "msbm", "Microsoft - Bus Mouse", "Busmouse", "BusMouse", "inportbm", TRUE }, + { "mousesystems", "Mouse Systems - Mouse (serial)", "MouseSystems", "MouseSystems", "ttyS", TRUE }, + { "mmseries", "MM - Series (serial)", "MMSeries", "MMSeries", "ttyS", TRUE }, + { "mmhittab", "MM - HitTablet (serial)", "MMHitTab", "MMHittab", "ttyS", TRUE }, + { "sun", "Sun - Mouse", "sun", "sun", "sunmouse", FALSE }, + { NULL, NULL, NULL, NULL, NULL, FALSE }, +}; + + + +/* + * This table maps between the mouse protocol name used for gpm and + * for the X server "protocol" mouse option. + */ + +typedef struct { + char *gpmproto; + char *Xproto; +} ProtocolEntry; + +static const ProtocolEntry __protocols[] = { + /* gpm protocol X protocol */ + { "ms3", "IntelliMouse" }, + { "Busmouse", "BusMouse" }, + { "Microsoft", "Microsoft" }, + { "imps2", "IMPS/2" }, + { "netmouse", "NetMousePS/2" }, + { "Logitech", "Logitech" }, + { "logim", "MouseMan" }, + { "MouseMan", "MouseMan" }, + { "ps/2", "PS/2" }, + { "pnp", "Auto" }, + { "MouseSystems", "MouseSystems" }, + { "MMSeries", "MMSeries" }, + { "MMHitTab", "MMHittab" }, + { "sun", "sun" }, + { NULL, NULL }, +}; + + +/* + * gpm_proto_to_X_proto() - map from gpm mouse protocol to X mouse + * protocol + */ + +static char* gpm_proto_to_X_proto(const char *gpm) +{ + int i; + + for (i = 0; __protocols[i].gpmproto; i++) { + if (strcmp(gpm, __protocols[i].gpmproto) == 0) { + return __protocols[i].Xproto; + } + } + return NULL; + +} /* gpm_proto_to_X_proto() */ + + + +/* + * find_mouse_entry() - scan the __mice[] table for the entry that + * corresponds to the specified value; return a pointer to the + * matching entry in the table, if any. + */ + +static const MouseEntry *find_mouse_entry(char *value) +{ + int i; + + if (!value) return NULL; + + for (i = 0; __mice[i].name; i++) { + if (strcmp(value, __mice[i].shortname) == 0) { + return &__mice[i]; + } + } + return NULL; + +} /* find_mouse_entry() */ + + + +/* + * find_closest_mouse_entry() - scan the __mice[] table for the entry that + * matches all of the specified values; any of the values can be NULL, + * in which case we do not use them as part of the comparison. Note + * that device is compared case sensitive, proto is compared case + * insensitive, and emulate3 is just a boolean. + */ + +static const MouseEntry *find_closest_mouse_entry(const char *device, + const char *proto, + const char *emulate3_str) +{ + int i; + int emulate3 = FALSE; + + /* + * translate the emulate3 string into a boolean we can use below + * for comparison + */ + + if ((emulate3_str) && + ((strcasecmp(emulate3_str, "yes") == 0) || + (strcasecmp(emulate3_str, "true") == 0) || + (strcasecmp(emulate3_str, "1") == 0))) { + emulate3 = TRUE; + } + + /* + * skip the "/dev/" part of the device filename + */ + + if (device && (strncmp(device, "/dev/", 5) == 0)) { + device += 5; /* strlen("/dev/") */ + } + + for (i = 0; __mice[i].name; i++) { + if ((device) && (strcmp(device, __mice[i].device) != 0)) continue; + if ((proto) && (strcasecmp(proto, __mice[i].Xproto)) != 0) continue; + if ((emulate3_str) && (emulate3 != __mice[i].emulate3)) continue; + return &__mice[i]; + } + + return NULL; + +} /* find_closest_mouse_entry() */ + + + +/* + * find_config_entry() - scan the specified filename for the specified + * keyword; return the value that the keyword is assigned to, or NULL + * if any error occurs. + */ + +static char *find_config_entry(const char *filename, const char *keyword) +{ + int fd = -1; + char *data = NULL; + char *value = NULL; + char *buf = NULL; + char *tmp, *start, *c, *end; + struct stat stat_buf; + size_t len; + + if ((fd = open(filename, O_RDONLY)) == -1) goto done; + + if (fstat(fd, &stat_buf) == -1) goto done; + + if ((data = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, + fd, 0)) == (void *) -1) goto done; + + /* + * create a sysmem copy of the buffer, so that we can explicitly + * NULL terminate it + */ + + buf = malloc(stat_buf.st_size + 1); + + if (!buf) goto done; + + memcpy(buf, data, stat_buf.st_size); + buf[stat_buf.st_size] = '\0'; + + /* search for the keyword */ + + start = buf; + + while (TRUE) { + tmp = strstr(start, keyword); + if (!tmp) goto done; + + /* + * make sure this line is not commented out: search back from + * tmp: if we hit a "#" before a newline, then this line is + * commented out and we should search again + */ + + c = tmp; + while ((c >= start) && (*c != '\n') && (*c != '#')) c--; + + if (*c == '#') { + /* keyword was commented out... search again */ + start = tmp+1; + } else { + /* keyword is not commented out */ + break; + } + } + + start = tmp + strlen(keyword); + end = strchr(start, '\n'); + if (!end) goto done; + + /* there must be something between the start and the end */ + + if (start == end) goto done; + + /* take what is between as the value */ + + len = end - start; + value = xconfigAlloc(len + 1); + strncpy(value, start, len); + value[len] = '\0'; + + /* if the first and last characters are quotation marks, remove them */ + + if ((value[0] == '\"') && (value[len-1] == '\"')) { + tmp = xconfigAlloc(len - 1); + strncpy(tmp, value + 1, len - 2); + tmp[len-2] = '\0'; + free(value); + value = tmp; + } + + done: + + if (buf) free(buf); + if (data) munmap(data, stat_buf.st_size); + if (fd != -1) close(fd); + + return value; + +} /* find_config_entry() */ + + + +/* + * xconfigGeneratePrintPossibleMice() - print the mouse table to stdout + */ + +void xconfigGeneratePrintPossibleMice(void) +{ + int i; + + printf("%-25s%-35s\n\n", "Short Name", "Name"); + + for (i = 0; __mice[i].name; i++) { + printf("%-25s%-35s\n", __mice[i].shortname, __mice[i].name); + } + + printf("\n"); + +} /* xconfigGeneratePrintPossibleMice() */ + + + +/* + * xconfigAddMouse() - determine the mouse type, and then add an + * XConfigInputRec with the appropriate options. + * + * - if the user specified on the commandline, use that + * + * - if /etc/sysconfig/mouse exists and contains valid data, use + * that + * + * - if /etc/conf.d/gpm exists and contains valid data, use that + * + * - infer the settings from the commandline options gpm is using XXX? + * + * - default to "auto" on /dev/mouse + */ + +int xconfigAddMouse(GenerateOptions *gop, XConfigPtr config) +{ + const MouseEntry *entry = NULL; + XConfigInputPtr input; + char *device_path, *comment = "default"; + + /* if the user specified on the commandline, use that */ + + if (gop->mouse) { + entry = find_mouse_entry(gop->mouse); + if (entry) { + comment = "commandline input"; + } else { + xconfigErrorMsg(WarnMsg, "Unable to find mouse \"%s\".", + gop->mouse); + } + } + + /* + * if /etc/sysconfig/mouse exists, and contains valid data, use + * that + */ + + if (!entry) { + char *protocol, *device, *emulate3; + + device = find_config_entry("/etc/sysconfig/mouse", "DEVICE="); + protocol = find_config_entry("/etc/sysconfig/mouse", "XMOUSETYPE="); + emulate3 = find_config_entry("/etc/sysconfig/mouse", "XEMU3="); + + if (device || protocol || emulate3) { + entry = find_closest_mouse_entry(device, protocol, emulate3); + if (entry) { + comment = "data in \"/etc/sysconfig/mouse\""; + } + } + } + + /* if /etc/conf.d/gpm exists and contains valid data, use that */ + + if (!entry) { + char *protocol, *device; + + protocol = find_config_entry("/etc/conf.d/gpm", "MOUSE="); + device = find_config_entry("/etc/conf.d/gpm", "MOUSEDEV="); + + if (protocol && device) { + MouseEntry *e = xconfigAlloc(sizeof(MouseEntry)); + e->shortname = "custom"; + e->name = "inferred from /etc/conf.d/gpm"; + e->gpmproto = protocol; + e->Xproto = gpm_proto_to_X_proto(protocol); + e->device = device + strlen("/dev/"); + e->emulate3 = FALSE; // XXX? + entry = e; + comment = "data in \"/etc/conf.d/gpm\""; + } + } + + /* + * XXX we could try to infer the settings from the commandline + * options gpm is using + */ + + if (!entry) { + /* XXX implement me */ + } + + /* at this point, we must have a mouse entry */ + + if (!entry) { + MouseEntry *e = xconfigAlloc(sizeof(MouseEntry)); + e->Xproto = "auto"; + +#if defined(NV_BSD) + e->device = "sysmouse"; +#else + if (access("/dev/psaux", F_OK) == 0) { + e->device = "psaux"; + } else if (access("/dev/input/mice", F_OK) == 0) { + e->device = "input/mice"; + } else { + e->device = "mouse"; + } +#endif + e->emulate3 = FALSE; + entry = e; + } + + /* add a new mouse input section */ + + input = xconfigAlloc(sizeof(XConfigInputRec)); + + input->comment = xconfigStrcat(" # generated from ", + comment, "\n", NULL); + input->identifier = xconfigStrdup("Mouse0"); + input->driver = xconfigStrdup("mouse"); + + device_path = xconfigStrcat("/dev/", entry->device, NULL); + + input->options = NULL; + xconfigAddNewOption(&input->options, "Protocol", entry->Xproto); + xconfigAddNewOption(&input->options, "Device", device_path); + xconfigAddNewOption(&input->options, "Emulate3Buttons", + (entry->emulate3 ? "yes" : "no")); + TEST_FREE(device_path); + + + /* + * This will make wheel mice work, and non-wheel mice should + * ignore ZAxisMapping + */ + + xconfigAddNewOption(&input->options, "ZAxisMapping", "4 5"); + + input->next = config->inputs; + config->inputs = input; + + return TRUE; + +} /* xconfigAddMouse() */ + + + + + +/*********************************************************************/ + +/* + * keyboard detection + */ + +typedef struct { + char *keytable; + char *name; + char *layout; /* XkbLayout */ + char *model; /* XkbModel */ + char *variant; /* XkbVariant */ + char *options; /* XkbOptions */ +} KeyboardEntry; + + +/* + * This table is based on data contained in + * /usr/lib/python2.2/site-packages/rhpl/keyboard_models.py on Red Hat + * Fedora core 1. That file contains the following copyright: + * + * + * keyboard_models.py - keyboard model list + * + * Brent Fox + * Mike Fulbright + * Jeremy Katz + * + * Copyright 2002 Red Hat, Inc. + */ + +static const KeyboardEntry __keyboards[] = { + + /* keytable name layout model variant options */ + + { "be-latin1", "Belgian (be-latin1)", "be", "pc105", NULL, NULL }, + { "bg", "Bulgarian", "bg,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "br-abnt2", "Brazilian (ABNT2)", "br", "abnt2", NULL, NULL }, + { "cf", "French Canadian", "ca_enhanced", "pc105", NULL, NULL }, + { "croat", "Croatian", "hr", "pc105", NULL, NULL }, + { "cz-us-qwertz", "Czechoslovakian (qwertz)", "cz,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "cz-lat2", "Czechoslovakian", "cz_qwerty", "pc105", NULL, NULL }, + { "de", "German", "de", "pc105", NULL, NULL }, + { "de-latin1", "German (latin1)", "de", "pc105", NULL, NULL }, + { "de-latin1-nodeadkeys", "German (latin1 w/ no deadkeys)", "de", "pc105", "nodeadkeys", NULL }, + { "dvorak", "Dvorak", "dvorak", "pc105", NULL, NULL }, + { "dk", "Danish", "dk", "pc105", NULL, NULL }, + { "dk-latin1", "Danish (latin1)", "dk", "pc105", NULL, NULL }, + { "es", "Spanish", "es", "pc105", NULL, NULL }, + { "et", "Estonian", "ee", "pc105", NULL, NULL }, + { "fi", "Finnish", "fi", "pc105", NULL, NULL }, + { "fi-latin1", "Finnish (latin1)", "fi", "pc105", NULL, NULL }, + { "fr", "French", "fr", "pc105", NULL, NULL }, + { "fr-latin0", "French (latin0)", "fr", "pc105", NULL, NULL }, + { "fr-latin1", "French (latin1)", "fr", "pc105", NULL, NULL }, + { "fr-pc", "French (pc)", "fr", "pc105", NULL, NULL }, + { "fr_CH", "Swiss French", "fr_CH", "pc105", NULL, NULL }, + { "fr_CH-latin1", "Swiss French (latin1)", "fr_CH", "pc105", NULL, NULL }, + { "gr", "Greek", "us,el", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "hu", "Hungarian", "hu", "pc105", NULL, NULL }, + { "hu101", "Hungarian (101 key)", "hu", "pc105", NULL, NULL }, + { "is-latin1", "Icelandic", "is", "pc105", NULL, NULL }, + { "it", "Italian", "it", "pc105", NULL, NULL }, + { "it-ibm", "Italian (IBM)", "it", "pc105", NULL, NULL }, + { "it2", "Italian (it2)", "it", "pc105", NULL, NULL }, + { "jp106", "Japanese", "jp", "jp106", NULL, NULL }, + { "la-latin1", "Latin American", "la", "pc105", NULL, NULL }, + { "mk-utf", "Macedonian", "mk,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "no", "Norwegian", "no", "pc105", NULL, NULL }, + { "pl", "Polish", "pl", "pc105", NULL, NULL }, + { "pt-latin1", "Portuguese", "pt", "pc105", NULL, NULL }, + { "ro_win", "Romanian", "ro", "pc105", NULL, NULL }, + { "ru", "Russian", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "ru-cp1251", "Russian (cp1251)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "ru-ms", "Russian (Microsoft)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "ru1", "Russian (ru1)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "ru2", "Russian (ru2)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "ru_win", "Russian (win)", "ru,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "speakup", "Speakup", "us", "pc105", NULL, NULL }, + { "speakup-lt", "Speakup (laptop)", "us", "pc105", NULL, NULL }, + { "sv-latin1", "Swedish", "se", "pc105", NULL, NULL }, + { "sg", "Swiss German", "de_CH", "pc105", NULL, NULL }, + { "sg-latin1", "Swiss German (latin1)", "de_CH", "pc105", NULL, NULL }, + { "sk-qwerty", "Slovakian", "sk_qwerty", "pc105", NULL, NULL }, + { "slovene", "Slovenian", "si", "pc105", NULL, NULL }, + { "trq", "Turkish", "tr", "pc105", NULL, NULL }, + { "uk", "United Kingdom", "gb", "pc105", NULL, NULL }, + { "ua", "Ukrainian", "ua,us", "pc105", NULL, "grp:shift_toggle,grp_led:scroll" }, + { "us-acentos", "U.S. International", "us_intl", "pc105", NULL, NULL }, + { "us", "U.S. English", "us", "pc105", NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL }, +}; + + + +/* + * find_keyboard_entry() - scan the __keyboards[] table for the entry that + * corresponds to the specified value; return a pointer to the + * matching entry in the table, if any. + */ + +static const KeyboardEntry *find_keyboard_entry(char *value) +{ + int i; + + if (!value) return NULL; + + for (i = 0; __keyboards[i].name; i++) { + if (strcmp(value, __keyboards[i].keytable) == 0) { + return &__keyboards[i]; + } + } + return NULL; + +} /* find_keyboard_entry() */ + + + +/* + * xconfigGeneratePrintPossibleKeyboards() - print the keyboard table + */ + +void xconfigGeneratePrintPossibleKeyboards(void) +{ + int i; + + printf("%-25s%-35s\n\n", "Short Name", "Name"); + + for (i = 0; __keyboards[i].name; i++) { + printf("%-25s%-35s\n", __keyboards[i].keytable, __keyboards[i].name); + } + + printf("\n"); + +} /* xconfigGeneratePrintPossibleKeyboards() */ + + + +/* + * xconfigAddKeyboard() - determine the keyboard type, and then add an + * XConfigInputRec with the appropriate options. + * + * How to detect the keyboard: + * + * - if the user specified on the command line, use that + * + * - if /etc/sysconfig/keyboard exists, and contains a valid + * KEYTABLE entry, use that + */ + +int xconfigAddKeyboard(GenerateOptions *gop, XConfigPtr config) +{ + char *value, *comment = "default"; + const KeyboardEntry *entry = NULL; + + XConfigInputPtr input; + + /* + * if the user specified on the command line, use that + */ + + if (gop->keyboard) { + entry = find_keyboard_entry(gop->keyboard); + if (entry) { + comment = "commandline input"; + } else { + xconfigErrorMsg(WarnMsg, "Unable to find keyboard \"%s\".", + gop->keyboard); + } + } + + /* + * if /etc/sysconfig/keyboard exists, and contains a valid + * KEYTABLE entry, use that + */ + + if (!entry) { + value = find_config_entry("/etc/sysconfig/keyboard", "KEYTABLE="); + entry = find_keyboard_entry(value); + if (value) { + free(value); + } + if (entry) { + comment = "data in \"/etc/sysconfig/keyboard\""; + } + } + + /* add a new keyboard input section */ + + input = xconfigAlloc(sizeof(XConfigInputRec)); + + input->comment = xconfigStrcat(" # generated from ", + comment, "\n", NULL); + input->identifier = xconfigStrdup("Keyboard0"); + + /* + * determine which keyboard driver should be used (either "kbd" or + * "keyboard"); if the user specified a keyboard driver use that; + * if 'ROOT/lib/modules/input/kbd_drv.(o|so)' exists, use "kbd"; + * otherwise, use "keyboard". + * On Solaris, use the default "keyboard" + */ + + if (gop->keyboard_driver) { + input->driver = gop->keyboard_driver; + } else { +#if defined(NV_SUNOS) || defined(NV_BSD) + input->driver = xconfigStrdup("keyboard"); +#else + input->driver = xconfigStrdup("kbd"); +#endif + } + + /* + * set additional keyboard options, based on the Keyboard table + * entry we found above + */ + + input->options = NULL; + + if (entry) { + if (entry->layout) + xconfigAddNewOption(&input->options, "XkbLayout", entry->layout); + if (entry->model) + xconfigAddNewOption(&input->options, "XkbModel", entry->model); + if (entry->variant) + xconfigAddNewOption(&input->options, "XkbVariant", entry->variant); + if (entry->options) + xconfigAddNewOption(&input->options, "XkbOptions", entry->options); + } + + input->next = config->inputs; + config->inputs = input; + + return TRUE; + +} /* xconfigAddKeyboard() */ + + + +/* + * xconfigGetDefaultProjectRoot() - scan some common directories for the X + * project root. + * + * Users of this information should be careful to account for the + * modular layout. + */ + +static char *xconfigGetDefaultProjectRoot(void) +{ + char *paths[] = { "/usr/X11R6", "/usr/X11", NULL }; + struct stat stat_buf; + int i; + + for (i = 0; paths[i]; i++) { + + if (stat(paths[i], &stat_buf) == -1) { + continue; + } + + if (S_ISDIR(stat_buf.st_mode)) { + return paths[i]; + } + } + + /* default to "/usr/X11R6", I guess */ + + return paths[0]; + +} /* xconfigGetDefaultProjectRoot() */ + + + + +/* + * get_xserver_information() - parse the versionString (from `X + * -version`) and assign relevant information that we infer from the X + * server version. + */ + +static int get_xserver_information(const char *versionString, + int *autoloadsGLX, + int *supportsExtensionSection, + int *xineramaPlusCompositeWorks, + const char **compositeExtensionName) +{ +#define XSERVER_VERSION_FORMAT_1 "X Window System Version" +#define XSERVER_VERSION_FORMAT_2 "X.Org X Server" + + int major, minor, found; + const char *ptr; + + /* check if this is an XFree86 X server */ + + if (strstr(versionString, "XFree86 Version")) { + xconfigErrorMsg(WarnMsg, "XFree86 is not supported."); + return FALSE; + } + + /* attempt to parse the major.minor version out of the string */ + + found = FALSE; + + if (((ptr = strstr(versionString, XSERVER_VERSION_FORMAT_1)) != NULL) && + (sscanf(ptr, XSERVER_VERSION_FORMAT_1 " %d.%d", &major, &minor) == 2)) { + found = TRUE; + } + + if (!found && + ((ptr = strstr(versionString, XSERVER_VERSION_FORMAT_2)) != NULL) && + (sscanf(ptr, XSERVER_VERSION_FORMAT_2 " %d.%d", &major, &minor) == 2)) { + found = TRUE; + } + + /* if we can't parse the version, give up */ + + if (!found) return FALSE; + + /* + * supportsExtensionSection: support for the "Extension" xorg.conf + * section was added between X.Org 6.7 and 6.8. To account for + * the X server version wrap, it is easier to check for X servers + * that do not support the Extension section: 6.x (x < 8) X + * servers. + */ + + if ((major == 6) && (minor < 8)) { + *supportsExtensionSection = FALSE; + } else { + *supportsExtensionSection = TRUE; + } + + /* + * support for autoloading GLX was added in X.Org 1.5. To account + * for the X server version wrap, it is easier to check for X + * servers that do not support GLX autoloading: 6.x, 7.x, or < 1.5 + * X servers. + */ + + if ((major == 6) || (major == 7) || ((major == 1) && (minor < 5))) { + *autoloadsGLX = FALSE; + } else { + *autoloadsGLX = TRUE; + } + + /* + * support for Xinerama and Composite at the same time works on X.Org + * xserver 1.15. + */ + + if ((major == 6) || (major == 7) || ((major == 1) && (minor < 15))) { + *xineramaPlusCompositeWorks = FALSE; + } else { + *xineramaPlusCompositeWorks = TRUE; + } + + /* + * With X.Org xserver version 1.20, the name of the composite + * extension was changed from "Composite" to "COMPOSITE". As of + * that release extension names are case-sensitive so we must + * ensure the correct case is used. + */ + if (major == 1 && minor >= 20) { + *compositeExtensionName = "COMPOSITE"; + } else { + *compositeExtensionName = "Composite"; + } + + return TRUE; + +} /* get_xserver_information() */ + + + +/* + * xconfigGetXServerInUse() - try to determine which X server is in use + * (XFree86, Xorg); also determine if the X server supports the + * Extension section of the X config file; support for the "Extension" + * section was added between X.Org 6.7 and 6.8. + * + * Some of the parsing here mimics what is done in the + * check_for_modular_xorg() function in nvidia-installer + */ + +#define NV_LINE_LEN 1024 +#define EXTRA_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/bin/X11" +#if defined(NV_SUNOS) +#define XSERVER_BIN_NAME "Xorg" +#else +#define XSERVER_BIN_NAME "X" +#endif + + +void xconfigGetXServerInUse(GenerateOptions *gop) +{ + FILE *stream = NULL; + int len, found; + char *cmd, *ptr, *ret; + + gop->supports_extension_section = FALSE; + gop->autoloads_glx = FALSE; + gop->xinerama_plus_composite_works = FALSE; + gop->compositeExtensionName = NULL; + + /* run `X -version` with a PATH that hopefully includes the X binary */ + + cmd = xconfigStrcat("PATH=", gop->x_project_root, ":", + EXTRA_PATH, ":$PATH ", XSERVER_BIN_NAME, + " -version 2>&1", NULL); + + if ((stream = popen(cmd, "r"))) { + char buf[NV_LINE_LEN]; + + /* read in as much of the input as we can fit into the buffer */ + + ptr = buf; + + do { + len = NV_LINE_LEN - (ptr - buf) - 1; + ret = fgets(ptr, len, stream); + ptr = strchr(ptr, '\0'); + } while ((ret != NULL) && (len > 1)); + + /* + * process the `X -version` output to infer relevant + * information from this X server + */ + + found = get_xserver_information(buf, + &gop->autoloads_glx, + &gop->supports_extension_section, + &gop->xinerama_plus_composite_works, + &gop->compositeExtensionName); + + if (!found) { + xconfigErrorMsg(WarnMsg, "Unable to parse X.Org version string."); + } + } + /* Close the popen()'ed stream. */ + pclose(stream); + free(cmd); + +} /* xconfigGetXServerInUse() */ + + + +/* + * xconfigGenerateLoadDefaultOptions - initialize a GenerateOptions + * structure with default values by peeking at the file system. + */ + +void xconfigGenerateLoadDefaultOptions(GenerateOptions *gop) +{ + memset(gop, 0, sizeof(GenerateOptions)); + + gop->x_project_root = xconfigGetDefaultProjectRoot(); + + /* XXX What to default the following to? + gop->keyboard + gop->mouse + gop->keyboard_driver + */ + +} /* xconfigGenerateLoadDefaultOptions() */ diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Input.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Input.c new file mode 100644 index 0000000..ea942b7 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Input.c @@ -0,0 +1,647 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static +XConfigSymTabRec InputTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {OPTION, "option"}, + {DRIVER, "driver"}, + {-1, ""}, +}; + +static +XConfigSymTabRec InputClassTab[] = +{ {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {MATCHPRODUCT, "matchproduct"}, + {MATCHVENDOR, "matchvendor"}, + {MATCHOS, "matchos"}, + {MATCHDEVICEPATH, "matchdevicepath"}, + {MATCHPNPID, "matchpnpid"}, + {MATCHUSBID, "matchusbid"}, + {MATCHDRIVER, "matchdriver"}, + {MATCHTAG, "matchtag"}, + {MATCHISKEYBOARD, "matchiskeyboard"}, + {MATCHISJOYSTICK, "matchisjoystick"}, + {MATCHISTABLET, "matchistablet"}, + {MATCHISTOUCHSCREEN, "matchistouchscreen"}, + {MATCHISTOUCHPAD, "matchistouchpad"}, + {MATCHISPOINTER, "matchispointer"}, + {OPTION, "option"}, + {DRIVER, "driver"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeInputList + +XConfigInputPtr +xconfigParseInputSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigInputPtr, XConfigInputRec) + + while ((token = xconfigGetToken (InputTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case DRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Driver"); + ptr->driver = val.str; + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP + +#define CLEANUP xconfigFreeInputClassList + +XConfigInputClassPtr +xconfigParseInputClassSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigInputClassPtr, XConfigInputClassRec) + + while ((token = xconfigGetToken (InputClassTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case DRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Driver"); + ptr->driver = val.str; + break; + case MATCHDEVICEPATH: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchDevicePath"); + ptr->match_device_path = val.str; + break; + case MATCHISPOINTER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchIsPointer"); + ptr->match_is_pointer = val.str; + break; + case MATCHISTOUCHPAD: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchIsTouchpad"); + ptr->match_is_touchpad = val.str; + break; + case MATCHISKEYBOARD: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchIsKeyboard"); + ptr->match_is_keyboard = val.str; + break; + case MATCHISTOUCHSCREEN: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchIsTouchscreen"); + ptr->match_is_touchscreen = val.str; + break; + case MATCHISJOYSTICK: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchIsJoystick"); + ptr->match_is_joystick = val.str; + break; + case MATCHISTABLET: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchIsTablet"); + ptr->match_is_tablet = val.str; + break; + case MATCHUSBID: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchUSBID"); + ptr->match_usb_id = val.str; + break; + case MATCHPNPID: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchPnPID"); + ptr->match_pnp_id = val.str; + break; + case MATCHPRODUCT: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchProduct"); + ptr->match_product = val.str; + break; + case MATCHDRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchDriver"); + ptr->match_driver = val.str; + break; + case MATCHOS: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchOS"); + ptr->match_os = val.str; + break; + case MATCHTAG: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchTag"); + ptr->match_tag = val.str; + break; + case MATCHVENDOR: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "MatchVendor"); + ptr->match_vendor = val.str; + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintInputSection (FILE * cf, XConfigInputPtr ptr) +{ + while (ptr) + { + fprintf (cf, "Section \"InputDevice\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + if (ptr->driver) + fprintf (cf, " Driver \"%s\"\n", ptr->driver); + xconfigPrintOptionList(cf, ptr->options, 1); + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigPrintInputClassSection (FILE * cf, XConfigInputClassPtr ptr) +{ + while (ptr) + { + fprintf (cf, "Section \"InputClass\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + if (ptr->driver) + fprintf (cf, " Driver \"%s\"\n", ptr->driver); + if (ptr->match_is_pointer) + fprintf (cf, " MatchIsPointer \"%s\"\n", ptr->match_is_pointer); + if (ptr->match_is_touchpad) + fprintf (cf, " MatchIsTouchpad \"%s\"\n", ptr->match_is_touchpad); + if (ptr->match_is_keyboard) + fprintf (cf, " MatchIsKeyboard \"%s\"\n", ptr->match_is_keyboard); + if (ptr->match_is_joystick) + fprintf (cf, " MatchIsJoystick \"%s\"\n", ptr->match_is_joystick); + if (ptr->match_is_touchscreen) + fprintf (cf, " MatchIsTouchscreen \"%s\"\n", ptr->match_is_touchscreen); + if (ptr->match_is_tablet) + fprintf (cf, " MatchIsTablet \"%s\"\n", ptr->match_is_tablet); + if (ptr->match_device_path) + fprintf (cf, " MatchDevicePath \"%s\"\n", ptr->match_device_path); + if (ptr->match_os) + fprintf (cf, " MatchOS \"%s\"\n", ptr->match_os); + if (ptr->match_pnp_id) + fprintf (cf, " MatchPnPID \"%s\"\n", ptr->match_pnp_id); + if (ptr->match_driver) + fprintf (cf, " MatchDriver \"%s\"\n", ptr->match_driver); + if (ptr->match_usb_id) + fprintf (cf, " MatchUSBID \"%s\"\n", ptr->match_usb_id); + if (ptr->match_tag) + fprintf (cf, " MatchTag \"%s\"\n", ptr->match_tag); + if (ptr->match_vendor) + fprintf (cf, " MatchVendor \"%s\"\n", ptr->match_vendor); + xconfigPrintOptionList(cf, ptr->options, 1); + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigFreeInputList (XConfigInputPtr *ptr) +{ + XConfigInputPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->driver); + TEST_FREE ((*ptr)->comment); + xconfigFreeOptionList (&((*ptr)->options)); + + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeInputClassList (XConfigInputClassPtr *ptr) +{ + XConfigInputClassPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->driver); + TEST_FREE ((*ptr)->comment); + TEST_FREE ((*ptr)->match_product); + TEST_FREE ((*ptr)->match_vendor); + TEST_FREE ((*ptr)->match_driver); + TEST_FREE ((*ptr)->match_device_path); + TEST_FREE ((*ptr)->match_os); + TEST_FREE ((*ptr)->match_pnp_id); + TEST_FREE ((*ptr)->match_usb_id); + TEST_FREE ((*ptr)->match_is_pointer); + TEST_FREE ((*ptr)->match_is_touchpad); + TEST_FREE ((*ptr)->match_is_touchscreen); + TEST_FREE ((*ptr)->match_is_keyboard); + TEST_FREE ((*ptr)->match_is_tablet); + TEST_FREE ((*ptr)->match_is_joystick); + xconfigFreeOptionList (&((*ptr)->options)); + + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +int +xconfigValidateInput (XConfigPtr p) +{ + XConfigInputPtr input = p->inputs; + +#if 0 /* Enable this later */ + if (!input) { + xconfigErrorMsg(ValidationErrorMsg, "At least one InputDevice section " + "is required."); + return (FALSE); + } +#endif + + while (input) { + if (!input->driver) { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_INPUTDRIVER_MSG, + input->identifier); + return (FALSE); + } + input = input->next; + } + return (TRUE); +} + +XConfigInputPtr +xconfigFindInput (const char *ident, XConfigInputPtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + +XConfigInputPtr +xconfigFindInputByDriver (const char *driver, XConfigInputPtr p) +{ + while (p) + { + if (xconfigNameCompare (driver, p->driver) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + + + +static int getCoreInputDevice(GenerateOptions *gop, + XConfigPtr config, + XConfigLayoutPtr layout, + const int mouse, + const char *coreKeyword, + const char *implicitDriverName, + const char *defaultDriver0, + const char *defaultDriver1, + const char *foundMsg0, + const char *foundMsg1) +{ + XConfigInputPtr input, core = NULL; + XConfigInputrefPtr inputRef; + int found, firstTry; + const char *found_msg = NULL; + + /* + * First check if the core input device has been specified in the + * active ServerLayout. If more than one is specified, remove the + * core attribute from the later ones. + */ + + for (inputRef = layout->inputs; inputRef; inputRef = inputRef->next) { + XConfigOptionPtr opt1 = NULL, opt2 = NULL; + + input = inputRef->input; + + opt1 = xconfigFindOption(input->options, coreKeyword); + opt2 = xconfigFindOption(inputRef->options, coreKeyword); + + if (opt1 || opt2) { + if (!core) { + core = input; + } else { + if (opt1) { + xconfigRemoveOption(&input->options, opt1); + } + if (opt2) { + xconfigRemoveOption(&inputRef->options, opt2); + } + xconfigErrorMsg(WarnMsg, "Duplicate %s devices; removing %s " + "attribute from \"%s\"\n", + coreKeyword, coreKeyword, input->identifier); + } + } + } + + /* + * XXX XFree86 allows the commandline to override the core input + * devices; let's not bother with that, here. + */ + + /* + * if we didn't find a core input device above in the + * serverLayout, scan through the config's entire input list and + * pick the first one with the coreKeyword. + */ + + if (!core) { + for (input = config->inputs; input; input = input->next) { + if (xconfigFindOption(input->options, coreKeyword)) { + core = input; + found_msg = foundMsg0; + break; + } + } + } + + /* + * if we didn't find a core input device above, then select the + * first input with the correct driver + */ + + firstTry = TRUE; + + tryAgain: + + if (!core) { + input = xconfigFindInput(implicitDriverName, config->inputs); + if (!input && defaultDriver0) { + input = xconfigFindInputByDriver(defaultDriver0, config->inputs); + } + if (!input && defaultDriver1) { + input = xconfigFindInputByDriver(defaultDriver1, config->inputs); + } + if (input) { + core = input; + found_msg = foundMsg1; + } + } + + /* + * if we didn't find a core input device above, then that means we + * don't have any input devices of this type; try to add a new + * input device of this type, and then try again to find a core + * input device + */ + + if (!core && firstTry) { + firstTry = FALSE; + + xconfigErrorMsg(WarnMsg, "Unable to find %s in X configuration; " + "attempting to add new %s section.", + coreKeyword, coreKeyword); + + if (mouse) { + xconfigAddMouse(gop, config); + } else { + xconfigAddKeyboard(gop, config); + } + goto tryAgain; + } + + /* + * if we *still* can't find a core input device, print a warning + * message and give up; hopefully the X server's builtin config + * will do. + */ + + if (!core) { + xconfigErrorMsg(WarnMsg, "Unable to determine %s; will rely on X " + "server's built-in default configuration.", + coreKeyword); + + /* don't return FALSE here -- we don't want nvidia-xconfig to fail */ + + return TRUE; + } + + + /* + * make sure the core input device is in the layout's input list + */ + + found = FALSE; + for (inputRef = layout->inputs; inputRef; inputRef = inputRef->next) { + if (inputRef->input == core) { + found = TRUE; + break; + } + } + if (!found) { + inputRef = calloc(1, sizeof(XConfigInputrefRec)); + inputRef->input = core; + inputRef->input_name = strdup(core->identifier); + inputRef->next = layout->inputs; + layout->inputs = inputRef; + } + + /* + * make sure the core input device has the core keyword set + */ + + for (inputRef = layout->inputs; inputRef; inputRef = inputRef->next) { + if (inputRef->input == core) { + XConfigOptionPtr opt1 = NULL, opt2 = NULL; + + opt1 = xconfigFindOption(inputRef->input->options, coreKeyword); + opt2 = xconfigFindOption(inputRef->options, coreKeyword); + + if (!opt1 && !opt2) { + xconfigAddNewOption(&inputRef->options, coreKeyword, NULL); + } + break; + } + } + + if (found_msg) { + xconfigErrorMsg(WarnMsg, "The %s device was not specified explicitly " + "in the layout; using the %s.\n", coreKeyword, found_msg); + } + + return TRUE; +} + + + +/* + * xconfigCheckCoreInputDevices() - check that the specified layout has a + * corePointer and coreKeyboard. If it does not have them, they will + * be added from the current list of input devices. + */ + +int xconfigCheckCoreInputDevices(GenerateOptions *gop, + XConfigPtr config, + XConfigLayoutPtr layout) +{ + int ret; + + ret = getCoreInputDevice(gop, + config, + layout, + TRUE, + "CorePointer", + CONF_IMPLICIT_POINTER, + "mouse", NULL, + "first CorePointer in the config input list", + "first mouse device"); + + if (!ret) return FALSE; + + ret = getCoreInputDevice(gop, + config, + layout, + FALSE, + "CoreKeyboard", + CONF_IMPLICIT_KEYBOARD, + "keyboard", "kbd", + "first CoreKeyboard in the config input list", + "first keyboard device"); + if (!ret) return FALSE; + + return TRUE; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Keyboard.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Keyboard.c new file mode 100644 index 0000000..f282eb6 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Keyboard.c @@ -0,0 +1,271 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" +#include "ctype.h" + +extern LexRec val; + +static XConfigSymTabRec KeyboardTab[] = +{ + {ENDSECTION, "endsection"}, + {KPROTOCOL, "protocol"}, + {AUTOREPEAT, "autorepeat"}, + {XLEDS, "xleds"}, + {PANIX106, "panix106"}, + {XKBKEYMAP, "xkbkeymap"}, + {XKBCOMPAT, "xkbcompat"}, + {XKBTYPES, "xkbtypes"}, + {XKBKEYCODES, "xkbkeycodes"}, + {XKBGEOMETRY, "xkbgeometry"}, + {XKBSYMBOLS, "xkbsymbols"}, + {XKBDISABLE, "xkbdisable"}, + {XKBRULES, "xkbrules"}, + {XKBMODEL, "xkbmodel"}, + {XKBLAYOUT, "xkblayout"}, + {XKBVARIANT, "xkbvariant"}, + {XKBOPTIONS, "xkboptions"}, + /* The next two have become ServerFlags options */ + {VTINIT, "vtinit"}, + {VTSYSREQ, "vtsysreq"}, + /* Obsolete keywords */ + {SERVERNUM, "servernumlock"}, + {LEFTALT, "leftalt"}, + {RIGHTALT, "rightalt"}, + {RIGHTALT, "altgr"}, + {SCROLLLOCK_TOK, "scrolllock"}, + {RIGHTCTL, "rightctl"}, + {-1, ""}, +}; + +/* Obsolete */ +static XConfigSymTabRec KeyMapTab[] = +{ + {CONF_KM_META, "meta"}, + {CONF_KM_COMPOSE, "compose"}, + {CONF_KM_MODESHIFT, "modeshift"}, + {CONF_KM_MODELOCK, "modelock"}, + {CONF_KM_SCROLLLOCK, "scrolllock"}, + {CONF_KM_CONTROL, "control"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeInputList + +XConfigInputPtr +xconfigParseKeyboardSection (void) +{ + char *s, *s1, *s2; + int l; + int token, ntoken; + PARSE_PROLOGUE (XConfigInputPtr, XConfigInputRec) + + while ((token = xconfigGetToken (KeyboardTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case KPROTOCOL: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Protocol"); + xconfigAddNewOption(&ptr->options, "Protocol", val.str); + break; + case AUTOREPEAT: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (AUTOREPEAT_MSG, NULL); + s1 = xconfigULongToString(val.num); + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (AUTOREPEAT_MSG, NULL); + s2 = xconfigULongToString(val.num); + l = strlen(s1) + 1 + strlen(s2) + 1; + s = malloc(l); + sprintf(s, "%s %s", s1, s2); + free(s1); + free(s2); + xconfigAddNewOption(&ptr->options, "AutoRepeat", s); + break; + case XLEDS: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (XLEDS_MSG, NULL); + s = xconfigULongToString(val.num); + l = strlen(s) + 1; + while ((token = xconfigGetSubToken(&(ptr->comment))) == NUMBER) + { + s1 = xconfigULongToString(val.num); + l += (1 + strlen(s1)); + s = realloc(s, l); + strcat(s, " "); + strcat(s, s1); + free(s1); + } + xconfigUnGetToken (token); + break; + case SERVERNUM: + xconfigErrorMsg(ParseWarningMsg, OBSOLETE_MSG, + xconfigTokenString()); + break; + case LEFTALT: + case RIGHTALT: + case SCROLLLOCK_TOK: + case RIGHTCTL: + xconfigErrorMsg(ParseWarningMsg, OBSOLETE_MSG, + xconfigTokenString()); + break; + ntoken = xconfigGetToken (KeyMapTab); + switch (ntoken) + { + case EOF_TOKEN: + xconfigErrorMsg(ParseErrorMsg, UNEXPECTED_EOF_MSG); + CLEANUP (&ptr); + return (NULL); + break; + + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + break; + case VTINIT: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "VTInit"); + xconfigErrorMsg(ParseWarningMsg, MOVED_TO_FLAGS_MSG, "VTInit"); + break; + case VTSYSREQ: + xconfigErrorMsg(ParseWarningMsg, + MOVED_TO_FLAGS_MSG, "VTSysReq"); + break; + case XKBDISABLE: + xconfigAddNewOption(&ptr->options, "XkbDisable", NULL); + break; + case XKBKEYMAP: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBKeymap"); + xconfigAddNewOption(&ptr->options, "XkbKeymap", val.str); + break; + case XKBCOMPAT: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBCompat"); + xconfigAddNewOption(&ptr->options, "XkbCompat", val.str); + break; + case XKBTYPES: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBTypes"); + xconfigAddNewOption(&ptr->options, "XkbTypes", val.str); + break; + case XKBKEYCODES: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBKeycodes"); + xconfigAddNewOption(&ptr->options, "XkbKeycodes", val.str); + break; + case XKBGEOMETRY: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBGeometry"); + xconfigAddNewOption(&ptr->options, "XkbGeometry", val.str); + break; + case XKBSYMBOLS: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBSymbols"); + xconfigAddNewOption(&ptr->options, "XkbSymbols", val.str); + break; + case XKBRULES: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBRules"); + xconfigAddNewOption(&ptr->options, "XkbRules", val.str); + break; + case XKBMODEL: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBModel"); + xconfigAddNewOption(&ptr->options, "XkbModel", val.str); + break; + case XKBLAYOUT: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBLayout"); + xconfigAddNewOption(&ptr->options, "XkbLayout", val.str); + break; + case XKBVARIANT: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBVariant"); + xconfigAddNewOption(&ptr->options, "XkbVariant", val.str); + break; + case XKBOPTIONS: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "XKBOptions"); + xconfigAddNewOption(&ptr->options, "XkbOptions", val.str); + break; + case PANIX106: + xconfigAddNewOption(&ptr->options, "Panix106", NULL); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + ptr->identifier = xconfigStrdup(CONF_IMPLICIT_KEYBOARD); + ptr->driver = xconfigStrdup("keyboard"); + xconfigAddNewOption(&ptr->options, "CoreKeyboard", NULL); + + return ptr; +} + diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Layout.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Layout.c new file mode 100644 index 0000000..1565556 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Layout.c @@ -0,0 +1,610 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" +#include + +extern LexRec val; + +static XConfigSymTabRec LayoutTab[] = +{ + {ENDSECTION, "endsection"}, + {SCREEN, "screen"}, + {IDENTIFIER, "identifier"}, + {INACTIVE, "inactive"}, + {INPUTDEVICE, "inputdevice"}, + {OPTION, "option"}, + {-1, ""}, +}; + +static XConfigSymTabRec AdjTab[] = +{ + {RIGHTOF, "rightof"}, + {LEFTOF, "leftof"}, + {ABOVE, "above"}, + {BELOW, "below"}, + {RELATIVE, "relative"}, + {ABSOLUTE, "absolute"}, + {-1, ""}, +}; + + +static int addImpliedLayout(XConfigPtr config, const char *screenName); + + +#define CLEANUP xconfigFreeLayoutList + +XConfigLayoutPtr +xconfigParseLayoutSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigLayoutPtr, XConfigLayoutRec) + + while ((token = xconfigGetToken (LayoutTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case INACTIVE: + { + XConfigInactivePtr iptr; + + iptr = calloc (1, sizeof (XConfigInactiveRec)); + iptr->next = NULL; + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (INACTIVE_MSG, NULL); + iptr->device_name = val.str; + xconfigAddListItem((GenericListPtr *)(&ptr->inactives), + (GenericListPtr) iptr); + } + break; + case SCREEN: + { + XConfigAdjacencyPtr aptr; + int absKeyword = 0; + + aptr = calloc (1, sizeof (XConfigAdjacencyRec)); + aptr->next = NULL; + aptr->scrnum = -1; + aptr->where = CONF_ADJ_OBSOLETE; + aptr->x = 0; + aptr->y = 0; + aptr->refscreen = NULL; + if ((token = xconfigGetSubToken (&(ptr->comment))) == NUMBER) + aptr->scrnum = val.num; + else + xconfigUnGetToken (token); + token = xconfigGetSubToken(&(ptr->comment)); + if (token != STRING) + Error (SCREEN_MSG, NULL); + aptr->screen_name = val.str; + + token = xconfigGetSubTokenWithTab(&(ptr->comment), AdjTab); + switch (token) + { + case RIGHTOF: + aptr->where = CONF_ADJ_RIGHTOF; + break; + case LEFTOF: + aptr->where = CONF_ADJ_LEFTOF; + break; + case ABOVE: + aptr->where = CONF_ADJ_ABOVE; + break; + case BELOW: + aptr->where = CONF_ADJ_BELOW; + break; + case RELATIVE: + aptr->where = CONF_ADJ_RELATIVE; + break; + case ABSOLUTE: + aptr->where = CONF_ADJ_ABSOLUTE; + absKeyword = 1; + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + xconfigUnGetToken (token); + token = xconfigGetSubToken(&(ptr->comment)); + if (token == STRING) + aptr->where = CONF_ADJ_OBSOLETE; + else + aptr->where = CONF_ADJ_ABSOLUTE; + } + switch (aptr->where) + { + case CONF_ADJ_ABSOLUTE: + if (absKeyword) + token = xconfigGetSubToken(&(ptr->comment)); + if (token == NUMBER) + { + aptr->x = val.num; + token = xconfigGetSubToken(&(ptr->comment)); + if (token != NUMBER) + Error(INVALID_SCR_MSG, NULL); + aptr->y = val.num; + } else { + if (absKeyword) + Error(INVALID_SCR_MSG, NULL); + else + xconfigUnGetToken (token); + } + break; + case CONF_ADJ_RIGHTOF: + case CONF_ADJ_LEFTOF: + case CONF_ADJ_ABOVE: + case CONF_ADJ_BELOW: + case CONF_ADJ_RELATIVE: + token = xconfigGetSubToken(&(ptr->comment)); + if (token != STRING) + Error(INVALID_SCR_MSG, NULL); + aptr->refscreen = val.str; + if (aptr->where == CONF_ADJ_RELATIVE) + { + token = xconfigGetSubToken(&(ptr->comment)); + if (token != NUMBER) + Error(INVALID_SCR_MSG, NULL); + aptr->x = val.num; + token = xconfigGetSubToken(&(ptr->comment)); + if (token != NUMBER) + Error(INVALID_SCR_MSG, NULL); + aptr->y = val.num; + } + break; + case CONF_ADJ_OBSOLETE: + /* top */ + aptr->top_name = val.str; + + /* bottom */ + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (SCREEN_MSG, NULL); + aptr->bottom_name = val.str; + + /* left */ + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (SCREEN_MSG, NULL); + aptr->left_name = val.str; + + /* right */ + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (SCREEN_MSG, NULL); + aptr->right_name = val.str; + + } + xconfigAddListItem((GenericListPtr *)(&ptr->adjacencies), + (GenericListPtr) aptr); + } + break; + case INPUTDEVICE: + { + XConfigInputrefPtr iptr; + + iptr = calloc (1, sizeof (XConfigInputrefRec)); + iptr->next = NULL; + iptr->options = NULL; + if (xconfigGetSubToken(&(ptr->comment)) != STRING) + Error (INPUTDEV_MSG, NULL); + iptr->input_name = val.str; + while ((token = xconfigGetSubToken(&(ptr->comment))) == STRING) { + xconfigAddNewOption(&iptr->options, val.str, NULL); + } + xconfigUnGetToken(token); + xconfigAddListItem((GenericListPtr *)(&ptr->inputs), + (GenericListPtr) iptr); + } + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintLayoutSection (FILE * cf, XConfigLayoutPtr ptr) +{ + XConfigAdjacencyPtr aptr; + XConfigInactivePtr iptr; + XConfigInputrefPtr inptr; + XConfigOptionPtr optr; + + while (ptr) + { + fprintf (cf, "Section \"ServerLayout\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + + for (aptr = ptr->adjacencies; aptr; aptr = aptr->next) + { + fprintf (cf, " Screen "); + if (aptr->scrnum >= 0) + fprintf (cf, "%2d", aptr->scrnum); + else + fprintf (cf, " "); + fprintf (cf, " \"%s\"", aptr->screen_name); + switch(aptr->where) + { + case CONF_ADJ_OBSOLETE: + fprintf (cf, " \"%s\"", aptr->top_name); + fprintf (cf, " \"%s\"", aptr->bottom_name); + fprintf (cf, " \"%s\"", aptr->right_name); + fprintf (cf, " \"%s\"\n", aptr->left_name); + break; + case CONF_ADJ_ABSOLUTE: + if (aptr->x != -1) + fprintf (cf, " %d %d\n", aptr->x, aptr->y); + else + fprintf (cf, "\n"); + break; + case CONF_ADJ_RIGHTOF: + fprintf (cf, " RightOf \"%s\"\n", aptr->refscreen); + break; + case CONF_ADJ_LEFTOF: + fprintf (cf, " LeftOf \"%s\"\n", aptr->refscreen); + break; + case CONF_ADJ_ABOVE: + fprintf (cf, " Above \"%s\"\n", aptr->refscreen); + break; + case CONF_ADJ_BELOW: + fprintf (cf, " Below \"%s\"\n", aptr->refscreen); + break; + case CONF_ADJ_RELATIVE: + fprintf (cf, " Relative \"%s\" %d %d\n", aptr->refscreen, + aptr->x, aptr->y); + break; + } + } + for (iptr = ptr->inactives; iptr; iptr = iptr->next) + fprintf (cf, " Inactive \"%s\"\n", iptr->device_name); + for (inptr = ptr->inputs; inptr; inptr = inptr->next) + { + fprintf (cf, " InputDevice \"%s\"", inptr->input_name); + for (optr = inptr->options; optr; optr = optr->next) + { + fprintf(cf, " \"%s\"", optr->name); + } + fprintf(cf, "\n"); + } + xconfigPrintOptionList(cf, ptr->options, 1); + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigFreeLayoutList (XConfigLayoutPtr *ptr) +{ + XConfigLayoutPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->comment); + xconfigFreeAdjacencyList (&((*ptr)->adjacencies)); + xconfigFreeInputrefList (&((*ptr)->inputs)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeAdjacencyList (XConfigAdjacencyPtr *ptr) +{ + XConfigAdjacencyPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->screen_name); + TEST_FREE ((*ptr)->top_name); + TEST_FREE ((*ptr)->bottom_name); + TEST_FREE ((*ptr)->left_name); + TEST_FREE ((*ptr)->right_name); + + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } + +} + +void +xconfigFreeInputrefList (XConfigInputrefPtr *ptr) +{ + XConfigInputrefPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->input_name); + xconfigFreeOptionList (&((*ptr)->options)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } + +} + +#define CheckScreen(str, ptr)\ +if (str[0] != '\0') \ +{ \ +screen = xconfigFindScreen (str, p->conf_screen_lst); \ +if (!screen) \ +{ \ + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_SCREEN_MSG, \ + str, layout->identifier); \ + return (FALSE); \ +} \ +else \ + ptr = screen; \ +} + +int +xconfigValidateLayout (XConfigPtr p) +{ + XConfigLayoutPtr layout = p->layouts; + XConfigAdjacencyPtr adj; + XConfigInactivePtr iptr; + XConfigInputrefPtr inputRef; + XConfigScreenPtr screen; + XConfigDevicePtr device; + XConfigInputPtr input; + + /* + * if we do not have a layout, just return TRUE; we'll add a + * layout later during the Sanitize step + */ + + if (!layout) return TRUE; + + while (layout) + { + adj = layout->adjacencies; + while (adj) + { + /* the first one can't be "" but all others can */ + screen = xconfigFindScreen (adj->screen_name, p->screens); + if (!screen) + { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_SCREEN_MSG, + adj->screen_name, layout->identifier); + return (FALSE); + } + else + adj->screen = screen; + +#if 0 + CheckScreen (adj->top_name, adj->top); + CheckScreen (adj->bottom_name, adj->bottom); + CheckScreen (adj->left_name, adj->left); + CheckScreen (adj->right_name, adj->right); +#endif + + adj = adj->next; + } + + + iptr = layout->inactives; + while (iptr) + { + device = xconfigFindDevice (iptr->device_name, + p->devices); + if (!device) + { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_DEVICE_MSG, + iptr->device_name, layout->identifier); + return (FALSE); + } + else + iptr->device = device; + iptr = iptr->next; + } + + /* + * the layout->inputs list is also updated in + * getCoreInputDevice() when no core input device is found in + * the layout's input list + */ + + inputRef = layout->inputs; + while (inputRef) + { + input = xconfigFindInput (inputRef->input_name, + p->inputs); + if (!input) + { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_INPUT_MSG, + inputRef->input_name, layout->identifier); + return (FALSE); + } + else { + inputRef->input = input; + } + inputRef = inputRef->next; + } + layout = layout->next; + } + return (TRUE); +} + +int +xconfigSanitizeLayout(XConfigPtr p, + const char *screenName, + GenerateOptions *gop) +{ + XConfigLayoutPtr layout = p->layouts; + + /* add an implicit layout if none exist */ + + if (!p->layouts) { + if (!addImpliedLayout(p, screenName)) { + return FALSE; + } + } + + /* check that input devices are assigned for each layout */ + + for (layout = p->layouts; layout; layout = layout->next) { + if (!xconfigCheckCoreInputDevices(gop, p, layout)) { + return FALSE; + } + } + + return TRUE; +} + +XConfigLayoutPtr +xconfigFindLayout (const char *name, XConfigLayoutPtr list) +{ + while (list) + { + if (xconfigNameCompare (list->identifier, name) == 0) + return (list); + list = list->next; + } + return (NULL); +} + + +static int addImpliedLayout(XConfigPtr config, const char *screenName) +{ + XConfigScreenPtr screen; + XConfigLayoutPtr layout; + XConfigAdjacencyPtr adj; + + if (config->layouts) return TRUE; + + /* + * which screen section is the active one? + * + * If there is a -screen option, use that one, otherwise use the first + * screen in the config's list. + */ + + if (screenName) { + screen = xconfigFindScreen(screenName, config->screens); + if (!screen) { + xconfigErrorMsg(ErrorMsg, "No Screen section called \"%s\"\n", + screenName); + return FALSE; + } + } else { + screen = config->screens; + } + + xconfigErrorMsg(WarnMsg, "No Layout specified, constructing implicit " + "layout section using screen \"%s\".\n", + screen->identifier); + + /* allocate the new layout section */ + + layout = calloc(1, sizeof(XConfigLayoutRec)); + + layout->identifier = xconfigStrdup("Default Layout"); + + adj = calloc(1, sizeof(XConfigAdjacencyRec)); + adj->scrnum = -1; + adj->screen = screen; + adj->screen_name = xconfigStrdup(screen->identifier); + + layout->adjacencies = adj; + + config->layouts = layout; + + /* validate the Layout here to setup all the pointers */ + + if (!xconfigValidateLayout(config)) return FALSE; + + return TRUE; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Merge.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Merge.c new file mode 100644 index 0000000..67ba8e2 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Merge.c @@ -0,0 +1,807 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + + + +/* + * xconfigAddRemovedOptionComment() - Makes a note in the comment + * string "existing_comments" that a particular option has been + * removed. + * + */ +static void xconfigAddRemovedOptionComment(char **existing_comments, + XConfigOptionPtr option) +{ + int len; + char *str; + char *name, *value; + + if (!option || !existing_comments) + return; + + name = xconfigOptionName(option); + value = xconfigOptionValue(option); + + if (!name) return; + + if (value) { + len = 32 + strlen(name) + strlen(value); + str = malloc(len); + if (!str) return; + snprintf(str, len, "# Removed Option \"%s\" \"%s\"", name, value); + } else { + len = 32 + strlen(name); + str = malloc(len); + if (!str) return; + snprintf(str, len, "# Removed Option \"%s\"", name); + } + + *existing_comments = xconfigAddComment(*existing_comments, str); + +} /* xconfigAddRemovedOptionComment() */ + + + +/* + * xconfigRemoveNamedOption() - Removes the named option from an option + * list and (if specified) adds a comment to an existing comments string + * + */ +void xconfigRemoveNamedOption(XConfigOptionPtr *pHead, const char *name, + char **comments) +{ + XConfigOptionPtr option; + + option = xconfigFindOption(*pHead, name); + if (option) { + if (comments) { + xconfigAddRemovedOptionComment(comments, option); + } + xconfigRemoveOption(pHead, option); + } + +} /* xconfigRemoveNamedOption() */ + + + +/* + * xconfigOptionValuesDiffer() - return '1' if the option values for + * option0 and option1 are different; return '0' if the option values + * are the same. + */ + +static int xconfigOptionValuesDiffer(XConfigOptionPtr option0, + XConfigOptionPtr option1) +{ + char *value0, *value1; + + value0 = value1 = NULL; + + if (!option0 && !option1) return 0; + if (!option0 && option1) return 1; + if ( option0 && !option1) return 1; + + value0 = xconfigOptionValue(option0); + value1 = xconfigOptionValue(option1); + + if (!value0 && !value1) return 0; + if (!value0 && value1) return 1; + if ( value0 && !value1) return 1; + + return (strcmp(value0, value1) != 0); + +} /* xconfigOptionValuesDiffer() */ + + + +/* + * xconfigMergeOption() - Merge option "name" from option source + * list "srcHead" to option destination list "dstHead". + * + * Merging here means: + * + * If the option is not in the source config, do nothing to the + * destination. Otherwise, either add or update the option in + * the dest. If the option is modified, and a comment is given, + * then the old option will be commented out instead of being + * simply removed/replaced. + */ +static void xconfigMergeOption(XConfigOptionPtr *dstHead, + XConfigOptionPtr *srcHead, + const char *name, char **comments) +{ + XConfigOptionPtr srcOption = xconfigFindOption(*srcHead, name); + XConfigOptionPtr dstOption = xconfigFindOption(*dstHead, name); + + char *srcValue = NULL; + + if (!srcOption) { + /* Option does not exist in src, do nothing to dst. */ + return; + } + + srcValue = xconfigOptionValue(srcOption); + + if (srcOption && !dstOption) { + + /* option exists in src but not in dst: add to dst */ + xconfigAddNewOption(dstHead, name, srcValue); + + } else if (srcOption && dstOption) { + + /* + * option exists in src and in dst; if the option values are + * different, replace the dst's option value with src's option + * value; note that xconfigAddNewOption() will remove the old + * option first, if necessary + */ + + if (xconfigOptionValuesDiffer(srcOption, dstOption)) { + if (comments) { + xconfigAddRemovedOptionComment(comments, dstOption); + } + xconfigAddNewOption(dstHead, name, srcValue); + } + } + +} /* xconfigMergeOption() */ + + + +/* + * xconfigMergeFlags() - Updates the destination's list of server flag + * options with the options found in the source config. + * + * Optons in the destination are either added or updated. Options that + * are found in the destination config and not in the source config are + * not modified. + * + * Returns 1 if the merge was successful and 0 if not. + */ +static int xconfigMergeFlags(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + if (srcConfig->flags) { + XConfigOptionPtr option; + + /* Flag section was not found, create a new one */ + if (!dstConfig->flags) { + dstConfig->flags = + (XConfigFlagsPtr) calloc(1, sizeof(XConfigFlagsRec)); + if (!dstConfig->flags) return 0; + } + + option = srcConfig->flags->options; + while (option) { + xconfigMergeOption(&(dstConfig->flags->options), + &(srcConfig->flags->options), + xconfigOptionName(option), + &(dstConfig->flags->comment)); + option = option->next; + } + } + + return 1; + +} /* xconfigMergeFlags() */ + + + +/* + * xconfigMergeMonitors() - Updates information in the destination monitor + * with that of the source monitor. + * + */ +static void xconfigMergeMonitors(XConfigMonitorPtr dstMonitor, + XConfigMonitorPtr srcMonitor) +{ + int i; + + + /* Update vendor */ + + free(dstMonitor->vendor); + dstMonitor->vendor = xconfigStrdup(srcMonitor->vendor); + + /* Update modelname */ + + free(dstMonitor->modelname); + dstMonitor->modelname = xconfigStrdup(srcMonitor->modelname); + + /* Update horizontal sync */ + + dstMonitor->n_hsync = srcMonitor->n_hsync; + for (i = 0; i < srcMonitor->n_hsync; i++) { + dstMonitor->hsync[i].lo = srcMonitor->hsync[i].lo; + dstMonitor->hsync[i].hi = srcMonitor->hsync[i].hi; + } + + /* Update vertical sync */ + + dstMonitor->n_vrefresh = srcMonitor->n_vrefresh; + for (i = 0; i < srcMonitor->n_hsync; i++) { + dstMonitor->vrefresh[i].lo = srcMonitor->vrefresh[i].lo; + dstMonitor->vrefresh[i].hi = srcMonitor->vrefresh[i].hi; + } + + /* XXX Remove the destination monitor's "UseModes" references to + * avoid having the wrong modelines tied to the new monitor. + */ + xconfigFreeModesLinkList(&dstMonitor->modes_sections); + +} /* xconfigMergeMonitors() */ + + + +/* + * xconfigMergeAllMonitors() - This function ensures that all monitors in + * the source config appear in the destination config by adding and/or + * updating the "appropriate" destination monitor sections. + * + */ +static int xconfigMergeAllMonitors(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + XConfigMonitorPtr dstMonitor; + XConfigMonitorPtr srcMonitor; + + + /* Make sure all monitors in the src config are also in the dst config */ + + for (srcMonitor = srcConfig->monitors; + srcMonitor; + srcMonitor = srcMonitor->next) { + + dstMonitor = + xconfigFindMonitor(srcMonitor->identifier, dstConfig->monitors); + + /* Monitor section was not found, create a new one and add it */ + if (!dstMonitor) { + dstMonitor = + (XConfigMonitorPtr) calloc(1, sizeof(XConfigMonitorRec)); + if (!dstMonitor) return 0; + + dstMonitor->identifier = xconfigStrdup(srcMonitor->identifier); + + xconfigAddListItem((GenericListPtr *)(&dstConfig->monitors), + (GenericListPtr)dstMonitor); + } + + /* Do the merge */ + xconfigMergeMonitors(dstMonitor, srcMonitor); + } + + return 1; + +} /* xconfigMergeAllMonitors() */ + + + +/* + * xconfigMergeDevices() - Updates information in the destination device + * with that of the source device. + * + */ +static void xconfigMergeDevices(XConfigDevicePtr dstDevice, + XConfigDevicePtr srcDevice) +{ + // XXX Zero out the device section? + + /* Update driver */ + + free(dstDevice->driver); + dstDevice->driver = xconfigStrdup(srcDevice->driver); + + /* Update vendor */ + + free(dstDevice->vendor); + dstDevice->vendor = xconfigStrdup(srcDevice->vendor); + + /* Update bus ID */ + + free(dstDevice->busid); + dstDevice->busid = xconfigStrdup(srcDevice->busid); + + /* Update board */ + + free(dstDevice->board); + dstDevice->board = xconfigStrdup(srcDevice->board); + + /* Update chip info */ + + dstDevice->chipid = srcDevice->chipid; + dstDevice->chiprev = srcDevice->chiprev; + + /* Update IRQ */ + + dstDevice->irq = srcDevice->irq; + + /* Update screen */ + + dstDevice->screen = srcDevice->screen; + +} /* xconfigMergeDevices() */ + + + +/* + * xconfigMergeAllDevices() - This function ensures that all devices in + * the source config appear in the destination config by adding and/or + * updating the "appropriate" destination device sections. + * + */ +static int xconfigMergeAllDevices(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + XConfigDevicePtr dstDevice; + XConfigDevicePtr srcDevice; + + + /* Make sure all monitors in the src config are also in the dst config */ + + for (srcDevice = srcConfig->devices; + srcDevice; + srcDevice = srcDevice->next) { + + dstDevice = + xconfigFindDevice(srcDevice->identifier, dstConfig->devices); + + /* Device section was not found, create a new one and add it */ + if (!dstDevice) { + dstDevice = + (XConfigDevicePtr) calloc(1, sizeof(XConfigDeviceRec)); + if (!dstDevice) return 0; + + dstDevice->identifier = xconfigStrdup(srcDevice->identifier); + + xconfigAddListItem((GenericListPtr *)(&dstConfig->devices), + (GenericListPtr)dstDevice); + } + + /* Do the merge */ + xconfigMergeDevices(dstDevice, srcDevice); + } + + return 1; + +} /* xconfigMergeAllDevices() */ + + + +/* + * xconfigMergeDriverOptions() - Update the (Screen) driver options + * of the destination config with information from the source config. + * + * - Assumes the source options are all found in the srcScreen->options. + * - Updates only those options listed in the srcScreen->options. + * + */ +static int xconfigMergeDriverOptions(XConfigScreenPtr dstScreen, + XConfigScreenPtr srcScreen) +{ + XConfigOptionPtr option; + XConfigDisplayPtr display; + + option = srcScreen->options; + while (option) { + char *name = xconfigOptionName(option); + + /* Remove the option from all non-screen option lists */ + + if (dstScreen->device) { + xconfigRemoveNamedOption(&(dstScreen->device->options), name, + &(dstScreen->device->comment)); + } + if (dstScreen->monitor) { + xconfigRemoveNamedOption(&(dstScreen->monitor->options), name, + &(dstScreen->monitor->comment)); + } + for (display = dstScreen->displays; display; display = display->next) { + xconfigRemoveNamedOption(&(display->options), name, + &(display->comment)); + } + + /* Update/Add the option to the screen's option list */ + { + // XXX Only add a comment if the value changed. + XConfigOptionPtr old = + xconfigFindOption(dstScreen->options, name); + + if (old && xconfigOptionValuesDiffer(option, old)) { + xconfigRemoveNamedOption(&(dstScreen->options), name, + &(dstScreen->comment)); + } else { + xconfigRemoveNamedOption(&(dstScreen->options), name, + NULL); + } + } + + /* Add the option to the screen->options list */ + + xconfigAddNewOption(&dstScreen->options, + name, xconfigOptionValue(option)); + + option = option->next; + } + + return 1; + +} /* xconfigMergeDriverOptions() */ + + + +/* + * xconfigMergeDisplays() - Duplicates display information from the + * source screen to the destination screen. + * + */ +static int xconfigMergeDisplays(XConfigScreenPtr dstScreen, + XConfigScreenPtr srcScreen) +{ + XConfigDisplayPtr dstDisplay; + XConfigDisplayPtr srcDisplay; + XConfigModePtr srcMode, dstMode, lastDstMode; + + /* Free all the displays in the destination screen */ + + xconfigFreeDisplayList(&dstScreen->displays); + + /* Copy all te displays */ + + for (srcDisplay = srcScreen->displays; + srcDisplay; + srcDisplay = srcDisplay->next) { + + /* Create a new display */ + + dstDisplay = xconfigAlloc(sizeof(XConfigDisplayRec)); + if (!dstDisplay) return 0; + + /* Copy display fields */ + + dstDisplay->frameX0 = srcDisplay->frameX0; + dstDisplay->frameY0 = srcDisplay->frameY0; + dstDisplay->virtualX = srcDisplay->virtualX; + dstDisplay->virtualY = srcDisplay->virtualY; + dstDisplay->depth = srcDisplay->depth; + dstDisplay->bpp = srcDisplay->bpp; + dstDisplay->visual = xconfigStrdup(srcDisplay->visual); + dstDisplay->weight = srcDisplay->weight; + dstDisplay->black = srcDisplay->black; + dstDisplay->white = srcDisplay->white; + dstDisplay->comment = xconfigStrdup(srcDisplay->comment); + + /* Copy options over */ + + dstDisplay->options = xconfigOptionListDup(srcDisplay->options); + + /* Copy modes over */ + + lastDstMode = NULL; + srcMode = srcDisplay->modes; + dstMode = NULL; + while (srcMode) { + + /* Copy the mode */ + + xconfigAddMode(&dstMode, srcMode->mode_name); + + /* Add mode at the end of the list */ + + if ( !lastDstMode ) { + dstDisplay->modes = dstMode; + } else { + lastDstMode->next = dstMode; + } + lastDstMode = dstMode; + + srcMode = srcMode->next; + } + + xconfigAddListItem((GenericListPtr *)(&dstScreen->displays), + (GenericListPtr)dstDisplay); + } + + return 1; + +} /* xconfigMergeDisplays() */ + + + +/* + * xconfigMergeScreens() - Updates information in the destination screen + * with that of the source screen. + * + * NOTE: This assumes the Monitor and Device sections have already been + * merged. + * + */ +static void xconfigMergeScreens(XConfigScreenPtr dstScreen, + XConfigPtr dstConfig, + XConfigScreenPtr srcScreen, + XConfigPtr srcConfig) +{ + /* Use the right device */ + + free(dstScreen->device_name); + dstScreen->device_name = xconfigStrdup(srcScreen->device_name); + dstScreen->device = + xconfigFindDevice(dstScreen->device_name, dstConfig->devices); + + + /* Use the right monitor */ + + free(dstScreen->monitor_name); + dstScreen->monitor_name = xconfigStrdup(srcScreen->monitor_name); + dstScreen->monitor = + xconfigFindMonitor(dstScreen->monitor_name, dstConfig->monitors); + + + /* Update the right default depth */ + + dstScreen->defaultdepth = srcScreen->defaultdepth; + + + /* Copy over the display section */ + + xconfigMergeDisplays(dstScreen, srcScreen); + + + /* Update the screen's driver options */ + + xconfigMergeDriverOptions(dstScreen, srcScreen); + +} /* xconfigMergeScreens() */ + + + +/* + * xconfigMergeAllScreens() - This function ensures that all screens in + * the source config appear in the destination config by adding and/or + * updating the "appropriate" destination screen sections. + * + */ +static int xconfigMergeAllScreens(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + XConfigScreenPtr srcScreen; + XConfigScreenPtr dstScreen; + + + /* Make sure all src screens are in the dst config */ + + for (srcScreen = srcConfig->screens; + srcScreen; + srcScreen = srcScreen->next) { + + dstScreen = + xconfigFindScreen(srcScreen->identifier, dstConfig->screens); + + /* Screen section was not found, create a new one and add it */ + if (!dstScreen) { + dstScreen = + (XConfigScreenPtr) calloc(1, sizeof(XConfigScreenRec)); + if (!dstScreen) return 0; + + dstScreen->identifier = xconfigStrdup(srcScreen->identifier); + + xconfigAddListItem((GenericListPtr *)(&dstConfig->screens), + (GenericListPtr)dstScreen); + } + + /* Do the merge */ + xconfigMergeScreens(dstScreen, dstConfig, srcScreen, srcConfig); + } + + return 1; + +} /* xconfigMergeAllScreens() */ + + + +/* + * xconfigMergeLayout() - Updates information in the destination's first + * layout with that of the source's first layout. + * + */ +static int xconfigMergeLayout(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + XConfigLayoutPtr srcLayout = srcConfig->layouts; + XConfigLayoutPtr dstLayout = dstConfig->layouts; + + XConfigAdjacencyPtr srcAdj; + XConfigAdjacencyPtr dstAdj; + XConfigAdjacencyPtr lastDstAdj; + + if (!dstLayout || !srcLayout) { + return 0; + } + + /* Clear the destination's adjacency list */ + + xconfigFreeAdjacencyList(&dstLayout->adjacencies); + + /* Copy adjacencies over */ + + lastDstAdj = NULL; + srcAdj = srcLayout->adjacencies; + while (srcAdj) { + + /* Copy the adjacency */ + + dstAdj = + (XConfigAdjacencyPtr) calloc(1, sizeof(XConfigAdjacencyRec)); + + dstAdj->scrnum = srcAdj->scrnum; + dstAdj->screen_name = xconfigStrdup(srcAdj->screen_name); + dstAdj->top_name = xconfigStrdup(srcAdj->top_name); + dstAdj->bottom_name = xconfigStrdup(srcAdj->bottom_name); + dstAdj->left_name = xconfigStrdup(srcAdj->left_name); + dstAdj->right_name = xconfigStrdup(srcAdj->right_name); + dstAdj->where = srcAdj->where; + dstAdj->x = srcAdj->x; + dstAdj->y = srcAdj->y; + dstAdj->refscreen = xconfigStrdup(srcAdj->refscreen); + + dstAdj->screen = + xconfigFindScreen(dstAdj->screen_name, dstConfig->screens); + dstAdj->top = + xconfigFindScreen(dstAdj->top_name, dstConfig->screens); + dstAdj->bottom = + xconfigFindScreen(dstAdj->bottom_name, dstConfig->screens); + dstAdj->left = + xconfigFindScreen(dstAdj->left_name, dstConfig->screens); + dstAdj->right = + xconfigFindScreen(dstAdj->right_name, dstConfig->screens); + + /* Add adjacency at the end of the list */ + + if (!lastDstAdj) { + dstLayout->adjacencies = dstAdj; + } else { + lastDstAdj->next = dstAdj; + } + lastDstAdj = dstAdj; + + srcAdj = srcAdj->next; + } + + /* Merge the options */ + + if (srcLayout->options) { + XConfigOptionPtr srcOption; + + srcOption = srcLayout->options; + while (srcOption) { + xconfigMergeOption(&(dstLayout->options), + &(srcLayout->options), + xconfigOptionName(srcOption), + &(dstLayout->comment)); + srcOption = srcOption->next; + } + } + + return 1; + +} /* xconfigMergeLayout() */ + + + +/* + * xconfigMergeExtensions() - Updates information in the destination's extension + * section with that of the source's extension section. + * Currently considering composite extension only. + * + */ +static int xconfigMergeExtensions(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + if (srcConfig->extensions) { + XConfigOptionPtr option; + + /* Extension section was not found, create a new one */ + if (!dstConfig->extensions) { + dstConfig->extensions = + (XConfigExtensionsPtr) calloc(1, sizeof(XConfigExtensionsRec)); + if (!dstConfig->extensions) return 0; + } + + option = srcConfig->extensions->options; + while (option) { + xconfigMergeOption(&(dstConfig->extensions->options), + &(srcConfig->extensions->options), + xconfigOptionName(option), + &(dstConfig->extensions->comment)); + option = option->next; + } + } + + return 1; + +} /* xconfigMergeExtensions() */ + +/* + * xconfigMergeConfigs() - Merges the source X configuration with the + * destination X configuration. + * + * NOTE: This function is currently only used for merging X config files + * for display configuration reasons. As such, the merge assumes + * that the dst config file is the target config file and that + * mostly, only new display configuration information should be + * copied from the source X config to the destination X config. + * + */ +int xconfigMergeConfigs(XConfigPtr dstConfig, XConfigPtr srcConfig) +{ + /* Make sure the X config is valid */ + // make_xconfig_usable(dstConfig); + + + /* Merge the server flag (Xinerama) section */ + + if (!xconfigMergeFlags(dstConfig, srcConfig)) { + return 0; + } + + + /* Merge the monitor sections */ + + if (!xconfigMergeAllMonitors(dstConfig, srcConfig)) { + return 0; + } + + + /* Merge the device sections */ + + if (!xconfigMergeAllDevices(dstConfig, srcConfig)) { + return 0; + } + + + /* Merge the screen sections */ + + if (!xconfigMergeAllScreens(dstConfig, srcConfig)) { + return 0; + } + + + /* Merge the first layout */ + + if (!xconfigMergeLayout(dstConfig, srcConfig)) { + return 0; + } + + /* Merge the extensions */ + + if (!xconfigMergeExtensions(dstConfig, srcConfig)) { + return 0; + } + + + return 1; + +} /* xconfigMergeConfigs() */ diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Module.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Module.c new file mode 100644 index 0000000..042a409 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Module.c @@ -0,0 +1,295 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec SubModuleTab[] = +{ + {ENDSUBSECTION, "endsubsection"}, + {OPTION, "option"}, + {-1, ""}, +}; + +static XConfigSymTabRec ModuleTab[] = +{ + {ENDSECTION, "endsection"}, + {LOAD, "load"}, + {LOAD_DRIVER, "loaddriver"}, + {DISABLE, "disable"}, + {SUBSECTION, "subsection"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeModules + +XConfigLoadPtr +xconfigParseModuleSubSection (XConfigLoadPtr head, char *name) +{ + int token; + PARSE_PROLOGUE (XConfigLoadPtr, XConfigLoadRec) + + ptr->name = name; + ptr->type = XCONFIG_LOAD_MODULE; + ptr->opt = NULL; + ptr->next = NULL; + + while ((token = xconfigGetToken (SubModuleTab)) != ENDSUBSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case OPTION: + ptr->opt = xconfigParseOption(ptr->opt); + break; + case EOF_TOKEN: + xconfigErrorMsg(ParseErrorMsg, UNEXPECTED_EOF_MSG); + free(ptr); + return NULL; + default: + xconfigErrorMsg(ParseErrorMsg, INVALID_KEYWORD_MSG, + xconfigTokenString()); + free(ptr); + return NULL; + break; + } + + } + + xconfigAddListItem((GenericListPtr *)(&head), (GenericListPtr)ptr); + return head; +} + +XConfigModulePtr +xconfigParseModuleSection (void) +{ + int token; + PARSE_PROLOGUE (XConfigModulePtr, XConfigModuleRec) + + while ((token = xconfigGetToken (ModuleTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case LOAD: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Load"); + xconfigAddNewLoadDirective (&ptr->loads, val.str, + XCONFIG_LOAD_MODULE, NULL, TRUE); + break; + case LOAD_DRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "LoadDriver"); + xconfigAddNewLoadDirective (&ptr->loads, val.str, + XCONFIG_LOAD_DRIVER, NULL, TRUE); + break; + case DISABLE: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Disable"); + xconfigAddNewLoadDirective (&ptr->disables, val.str, + XCONFIG_DISABLE_MODULE, NULL, TRUE); + break; + case SUBSECTION: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "SubSection"); + ptr->loads = + xconfigParseModuleSubSection (ptr->loads, val.str); + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintModuleSection (FILE * cf, XConfigModulePtr ptr) +{ + XConfigLoadPtr lptr; + + if (ptr == NULL) + return; + + if (ptr->comment) + fprintf(cf, "%s", ptr->comment); + for (lptr = ptr->loads; lptr; lptr = lptr->next) + { + switch (lptr->type) + { + case XCONFIG_LOAD_MODULE: + if( lptr->opt == NULL ) { + fprintf (cf, " Load \"%s\"", lptr->name); + if (lptr->comment) + fprintf(cf, "%s", lptr->comment); + else + fputc('\n', cf); + } + else + { + fprintf (cf, " SubSection \"%s\"\n", lptr->name); + if (lptr->comment) + fprintf(cf, "%s", lptr->comment); + xconfigPrintOptionList(cf, lptr->opt, 2); + fprintf (cf, " EndSubSection\n"); + } + break; + case XCONFIG_LOAD_DRIVER: + fprintf (cf, " LoadDriver \"%s\"", lptr->name); + if (lptr->comment) + fprintf(cf, "%s", lptr->comment); + else + fputc('\n', cf); + break; +#if 0 + default: + fprintf (cf, "# Unknown type \"%s\"\n", lptr->name); + break; +#endif + } + } + for (lptr = ptr->disables; lptr; lptr = lptr->next) + { + switch (lptr->type) + { + case XCONFIG_DISABLE_MODULE: + fprintf (cf, " Disable \"%s\"", lptr->name); + if (lptr->comment) + fprintf(cf, "%s", lptr->comment); + else + fputc('\n', cf); + break; + } + } +} + +void +xconfigAddNewLoadDirective (XConfigLoadPtr *pHead, char *name, int type, + XConfigOptionPtr opts, int do_token) +{ + XConfigLoadPtr new; + int token; + + new = calloc (1, sizeof (XConfigLoadRec)); + new->name = name; + new->type = type; + new->opt = opts; + new->next = NULL; + + if (do_token) { + if ((token = xconfigGetToken(NULL)) == COMMENT) { + new->comment = xconfigAddComment(new->comment, val.str); + } else { + xconfigUnGetToken(token); + } + } + + xconfigAddListItem((GenericListPtr *)pHead, (GenericListPtr)new); +} + +void +xconfigRemoveLoadDirective(XConfigLoadPtr *pHead, XConfigLoadPtr load) +{ + xconfigRemoveListItem((GenericListPtr *)pHead, (GenericListPtr)load); + + TEST_FREE(load->name); + TEST_FREE(load->comment); + xconfigFreeOptionList(&(load->opt)); + free(load); +} + +static void +FreeModule(XConfigLoadPtr lptr) +{ + XConfigLoadPtr prev; + + while (lptr) + { + TEST_FREE (lptr->name); + TEST_FREE (lptr->comment); + prev = lptr; + lptr = lptr->next; + free (prev); + } +} + +void +xconfigFreeModules (XConfigModulePtr *ptr) +{ + if (ptr == NULL || *ptr == NULL) + return; + + FreeModule((*ptr)->loads); + FreeModule((*ptr)->disables); + + TEST_FREE ((*ptr)->comment); + free (*ptr); + *ptr = NULL; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Monitor.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Monitor.c new file mode 100644 index 0000000..6a8fd00 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Monitor.c @@ -0,0 +1,921 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec MonitorTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {VENDOR, "vendorname"}, + {MODEL, "modelname"}, + {USEMODES, "usemodes"}, + {MODELINE, "modeline"}, + {DISPLAYSIZE, "displaysize"}, + {HORIZSYNC, "horizsync"}, + {VERTREFRESH, "vertrefresh"}, + {MODE, "mode"}, + {GAMMA, "gamma"}, + {OPTION, "option"}, + {-1, ""}, +}; + +static XConfigSymTabRec ModesTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {MODELINE, "modeline"}, + {MODE, "mode"}, + {-1, ""}, +}; + +static XConfigSymTabRec TimingTab[] = +{ + {TT_INTERLACE, "interlace"}, + {TT_PHSYNC, "+hsync"}, + {TT_NHSYNC, "-hsync"}, + {TT_PVSYNC, "+vsync"}, + {TT_NVSYNC, "-vsync"}, + {TT_CSYNC, "composite"}, + {TT_PCSYNC, "+csync"}, + {TT_NCSYNC, "-csync"}, + {TT_DBLSCAN, "doublescan"}, + {TT_HSKEW, "hskew"}, + {TT_BCAST, "bcast"}, + {TT_VSCAN, "vscan"}, + {TT_CUSTOM, "CUSTOM"}, + {-1, ""}, +}; + +static XConfigSymTabRec ModeTab[] = +{ + {DOTCLOCK, "dotclock"}, + {HTIMINGS, "htimings"}, + {VTIMINGS, "vtimings"}, + {FLAGS, "flags"}, + {HSKEW, "hskew"}, + {BCAST, "bcast"}, + {VSCAN, "vscan"}, + {ENDMODE, "endmode"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeModeLineList + +XConfigModeLinePtr +xconfigParseModeLine (void) +{ + int token; + PARSE_PROLOGUE (XConfigModeLinePtr, XConfigModeLineRec) + + /* Identifier */ + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error ("ModeLine identifier expected", NULL); + ptr->identifier = val.str; + + /* DotClock */ + if ((xconfigGetSubToken (&(ptr->comment)) != NUMBER) || !val.str) + Error ("ModeLine dotclock expected", NULL); + ptr->clock = xconfigStrdup(val.str); + + /* HDisplay */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine Hdisplay expected", NULL); + ptr->hdisplay = val.num; + + /* HSyncStart */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine HSyncStart expected", NULL); + ptr->hsyncstart = val.num; + + /* HSyncEnd */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine HSyncEnd expected", NULL); + ptr->hsyncend = val.num; + + /* HTotal */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine HTotal expected", NULL); + ptr->htotal = val.num; + + /* VDisplay */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine Vdisplay expected", NULL); + ptr->vdisplay = val.num; + + /* VSyncStart */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine VSyncStart expected", NULL); + ptr->vsyncstart = val.num; + + /* VSyncEnd */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine VSyncEnd expected", NULL); + ptr->vsyncend = val.num; + + /* VTotal */ + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("ModeLine VTotal expected", NULL); + ptr->vtotal = val.num; + + token = xconfigGetSubTokenWithTab (&(ptr->comment), TimingTab); + while ((token == TT_INTERLACE) || (token == TT_PHSYNC) || + (token == TT_NHSYNC) || (token == TT_PVSYNC) || + (token == TT_NVSYNC) || (token == TT_CSYNC) || + (token == TT_PCSYNC) || (token == TT_NCSYNC) || + (token == TT_DBLSCAN) || (token == TT_HSKEW) || + (token == TT_VSCAN) || (token == TT_BCAST)) + { + switch (token) + { + + case TT_INTERLACE: + ptr->flags |= XCONFIG_MODE_INTERLACE; + break; + case TT_PHSYNC: + ptr->flags |= XCONFIG_MODE_PHSYNC; + break; + case TT_NHSYNC: + ptr->flags |= XCONFIG_MODE_NHSYNC; + break; + case TT_PVSYNC: + ptr->flags |= XCONFIG_MODE_PVSYNC; + break; + case TT_NVSYNC: + ptr->flags |= XCONFIG_MODE_NVSYNC; + break; + case TT_CSYNC: + ptr->flags |= XCONFIG_MODE_CSYNC; + break; + case TT_PCSYNC: + ptr->flags |= XCONFIG_MODE_PCSYNC; + break; + case TT_NCSYNC: + ptr->flags |= XCONFIG_MODE_NCSYNC; + break; + case TT_DBLSCAN: + ptr->flags |= XCONFIG_MODE_DBLSCAN; + break; + case TT_HSKEW: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "Hskew"); + ptr->hskew = val.num; + ptr->flags |= XCONFIG_MODE_HSKEW; + break; + case TT_BCAST: + ptr->flags |= XCONFIG_MODE_BCAST; + break; + case TT_VSCAN: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "Vscan"); + ptr->vscan = val.num; + ptr->flags |= XCONFIG_MODE_VSCAN; + break; + case TT_CUSTOM: + ptr->flags |= XCONFIG_MODE_CUSTOM; + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + token = xconfigGetSubTokenWithTab (&(ptr->comment), TimingTab); + } + xconfigUnGetToken (token); + + return (ptr); +} + +XConfigModeLinePtr +xconfigParseVerboseMode (void) +{ + int token, token2; + int had_dotclock = 0, had_htimings = 0, had_vtimings = 0; + PARSE_PROLOGUE (XConfigModeLinePtr, XConfigModeLineRec) + + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error ("Mode name expected", NULL); + ptr->identifier = val.str; + while ((token = xconfigGetToken (ModeTab)) != ENDMODE) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case DOTCLOCK: + if ((xconfigGetSubToken (&(ptr->comment)) != NUMBER) || !val.str) + Error (NUMBER_MSG, "DotClock"); + ptr->clock = xconfigStrdup(val.str); + had_dotclock = 1; + break; + case HTIMINGS: + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->hdisplay = val.num; + else + Error ("Horizontal display expected", NULL); + + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->hsyncstart = val.num; + else + Error ("Horizontal sync start expected", NULL); + + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->hsyncend = val.num; + else + Error ("Horizontal sync end expected", NULL); + + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->htotal = val.num; + else + Error ("Horizontal total expected", NULL); + had_htimings = 1; + break; + case VTIMINGS: + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->vdisplay = val.num; + else + Error ("Vertical display expected", NULL); + + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->vsyncstart = val.num; + else + Error ("Vertical sync start expected", NULL); + + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->vsyncend = val.num; + else + Error ("Vertical sync end expected", NULL); + + if (xconfigGetSubToken (&(ptr->comment)) == NUMBER) + ptr->vtotal = val.num; + else + Error ("Vertical total expected", NULL); + had_vtimings = 1; + break; + case FLAGS: + token = xconfigGetSubToken (&(ptr->comment)); + if (token != STRING) + Error (QUOTE_MSG, "Flags"); + while (token == STRING) + { + token2 = xconfigGetStringToken (TimingTab); + switch (token2) + { + case TT_INTERLACE: + ptr->flags |= XCONFIG_MODE_INTERLACE; + break; + case TT_PHSYNC: + ptr->flags |= XCONFIG_MODE_PHSYNC; + break; + case TT_NHSYNC: + ptr->flags |= XCONFIG_MODE_NHSYNC; + break; + case TT_PVSYNC: + ptr->flags |= XCONFIG_MODE_PVSYNC; + break; + case TT_NVSYNC: + ptr->flags |= XCONFIG_MODE_NVSYNC; + break; + case TT_CSYNC: + ptr->flags |= XCONFIG_MODE_CSYNC; + break; + case TT_PCSYNC: + ptr->flags |= XCONFIG_MODE_PCSYNC; + break; + case TT_NCSYNC: + ptr->flags |= XCONFIG_MODE_NCSYNC; + break; + case TT_DBLSCAN: + ptr->flags |= XCONFIG_MODE_DBLSCAN; + break; + case TT_CUSTOM: + ptr->flags |= XCONFIG_MODE_CUSTOM; + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error ("Unknown flag string", NULL); + break; + } + token = xconfigGetSubToken (&(ptr->comment)); + } + xconfigUnGetToken (token); + break; + case HSKEW: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("Horizontal skew expected", NULL); + ptr->flags |= XCONFIG_MODE_HSKEW; + ptr->hskew = val.num; + break; + case VSCAN: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error ("Vertical scan count expected", NULL); + ptr->flags |= XCONFIG_MODE_VSCAN; + ptr->vscan = val.num; + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error ("Unexepcted token in verbose \"Mode\" entry\n", NULL); + } + } + if (!had_dotclock) + Error ("the dotclock is missing", NULL); + if (!had_htimings) + Error ("the horizontal timings are missing", NULL); + if (!had_vtimings) + Error ("the vertical timings are missing", NULL); + + return (ptr); +} + +#undef CLEANUP + +#define CLEANUP xconfigFreeMonitorList + +XConfigMonitorPtr +xconfigParseMonitorSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigMonitorPtr, XConfigMonitorRec) + + while ((token = xconfigGetToken (MonitorTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case VENDOR: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Vendor"); + ptr->vendor = val.str; + break; + case MODEL: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "ModelName"); + ptr->modelname = val.str; + break; + case MODE: + HANDLE_LIST (modelines, xconfigParseVerboseMode, + XConfigModeLinePtr); + break; + case MODELINE: + HANDLE_LIST (modelines, xconfigParseModeLine, + XConfigModeLinePtr); + break; + case DISPLAYSIZE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (DISPLAYSIZE_MSG, NULL); + ptr->width = val.realnum; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (DISPLAYSIZE_MSG, NULL); + ptr->height = val.realnum; + break; + + case HORIZSYNC: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (HORIZSYNC_MSG, NULL); + do { + ptr->hsync[ptr->n_hsync].lo = val.realnum; + switch (token = xconfigGetSubToken (&(ptr->comment))) + { + case COMMA: + ptr->hsync[ptr->n_hsync].hi = + ptr->hsync[ptr->n_hsync].lo; + break; + case DASH: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || + (float)val.realnum < ptr->hsync[ptr->n_hsync].lo) + Error (HORIZSYNC_MSG, NULL); + ptr->hsync[ptr->n_hsync].hi = val.realnum; + if ((token = xconfigGetSubToken (&(ptr->comment))) == COMMA) + break; + ptr->n_hsync++; + goto HorizDone; + default: + /* We cannot currently know if a '\n' was found, + * or this is a real error + */ + ptr->hsync[ptr->n_hsync].hi = + ptr->hsync[ptr->n_hsync].lo; + ptr->n_hsync++; + goto HorizDone; + } + if (ptr->n_hsync >= CONF_MAX_HSYNC) + Error ("Sorry. Too many horizontal sync intervals.", NULL); + ptr->n_hsync++; + } while ((token = xconfigGetSubToken (&(ptr->comment))) == NUMBER); +HorizDone: + xconfigUnGetToken (token); + break; + + case VERTREFRESH: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (VERTREFRESH_MSG, NULL); + do { + ptr->vrefresh[ptr->n_vrefresh].lo = val.realnum; + switch (token = xconfigGetSubToken (&(ptr->comment))) + { + case COMMA: + ptr->vrefresh[ptr->n_vrefresh].hi = + ptr->vrefresh[ptr->n_vrefresh].lo; + break; + case DASH: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || + (float)val.realnum < ptr->vrefresh[ptr->n_vrefresh].lo) + Error (VERTREFRESH_MSG, NULL); + ptr->vrefresh[ptr->n_vrefresh].hi = val.realnum; + if ((token = xconfigGetSubToken (&(ptr->comment))) == COMMA) + break; + ptr->n_vrefresh++; + goto VertDone; + default: + /* We cannot currently know if a '\n' was found, + * or this is a real error + */ + ptr->vrefresh[ptr->n_vrefresh].hi = + ptr->vrefresh[ptr->n_vrefresh].lo; + ptr->n_vrefresh++; + goto VertDone; + } + if (ptr->n_vrefresh >= CONF_MAX_VREFRESH) + Error ("Sorry. Too many vertical refresh intervals.", NULL); + ptr->n_vrefresh++; + } while ((token = xconfigGetSubToken (&(ptr->comment))) == NUMBER); +VertDone: + xconfigUnGetToken (token); + break; + + case GAMMA: + if( xconfigGetSubToken (&(ptr->comment)) != NUMBER ) + { + Error (INVALID_GAMMA_MSG, NULL); + } + else + { + ptr->gamma_red = ptr->gamma_green = + ptr->gamma_blue = val.realnum; + if( xconfigGetSubToken (&(ptr->comment)) == NUMBER ) + { + ptr->gamma_green = val.realnum; + if( xconfigGetSubToken (&(ptr->comment)) == NUMBER ) + { + ptr->gamma_blue = val.realnum; + } + else + { + Error (INVALID_GAMMA_MSG, NULL); + } + } + else + xconfigUnGetToken (token); + } + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case USEMODES: + { + XConfigModesLinkPtr mptr; + + if ((token = xconfigGetSubToken (&(ptr->comment))) != STRING) + Error (QUOTE_MSG, "UseModes"); + + /* add to the end of the list of modes sections + referenced here */ + mptr = calloc (1, sizeof (XConfigModesLinkRec)); + mptr->next = NULL; + mptr->modes_name = val.str; + mptr->modes = NULL; + xconfigAddListItem((GenericListPtr *)(&ptr->modes_sections), + (GenericListPtr)mptr); + } + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + xconfigErrorMsg(ParseErrorMsg, INVALID_KEYWORD_MSG, + xconfigTokenString()); + CLEANUP (&ptr); + return NULL; + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP +#define CLEANUP xconfigFreeModesList + +XConfigModesPtr +xconfigParseModesSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigModesPtr, XConfigModesRec) + + while ((token = xconfigGetToken (ModesTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case MODE: + HANDLE_LIST (modelines, xconfigParseVerboseMode, + XConfigModeLinePtr); + break; + case MODELINE: + HANDLE_LIST (modelines, xconfigParseModeLine, + XConfigModeLinePtr); + break; + default: + xconfigErrorMsg(ParseErrorMsg, INVALID_KEYWORD_MSG, + xconfigTokenString()); + CLEANUP (&ptr); + return NULL; + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintMonitorSection (FILE * cf, XConfigMonitorPtr ptr) +{ + int i; + XConfigModeLinePtr mlptr; + XConfigModesLinkPtr mptr; + + while (ptr) + { + mptr = ptr->modes_sections; + fprintf (cf, "Section \"Monitor\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + if (ptr->vendor) + fprintf (cf, " VendorName \"%s\"\n", ptr->vendor); + if (ptr->modelname) + fprintf (cf, " ModelName \"%s\"\n", ptr->modelname); + while (mptr) { + fprintf (cf, " UseModes \"%s\"\n", mptr->modes_name); + mptr = mptr->next; + } + if (ptr->width) + fprintf (cf, " DisplaySize %d %d\n", + ptr->width, + ptr->height); + for (i = 0; i < ptr->n_hsync; i++) + { + fprintf (cf, " HorizSync %2.1f - %2.1f\n", + ptr->hsync[i].lo, + ptr->hsync[i].hi); + } + for (i = 0; i < ptr->n_vrefresh; i++) + { + if (ptr->vrefresh[i].lo == ptr->vrefresh[i].hi) { + fprintf (cf, " VertRefresh %2.1f\n", + ptr->vrefresh[i].lo); + } else { + fprintf (cf, " VertRefresh %2.1f - %2.1f\n", + ptr->vrefresh[i].lo, + ptr->vrefresh[i].hi); + } + } + if (ptr->gamma_red) { + if (ptr->gamma_red == ptr->gamma_green + && ptr->gamma_red == ptr->gamma_blue) + { + fprintf (cf, " Gamma %.4g\n", + ptr->gamma_red); + } else { + fprintf (cf, " Gamma %.4g %.4g %.4g\n", + ptr->gamma_red, + ptr->gamma_green, + ptr->gamma_blue); + } + } + for (mlptr = ptr->modelines; mlptr; mlptr = mlptr->next) + { + fprintf (cf, " ModeLine \"%s\" %s ", + mlptr->identifier, mlptr->clock); + fprintf (cf, "%d %d %d %d %d %d %d %d", + mlptr->hdisplay, mlptr->hsyncstart, + mlptr->hsyncend, mlptr->htotal, + mlptr->vdisplay, mlptr->vsyncstart, + mlptr->vsyncend, mlptr->vtotal); + if (mlptr->flags & XCONFIG_MODE_PHSYNC) + fprintf (cf, " +hsync"); + if (mlptr->flags & XCONFIG_MODE_NHSYNC) + fprintf (cf, " -hsync"); + if (mlptr->flags & XCONFIG_MODE_PVSYNC) + fprintf (cf, " +vsync"); + if (mlptr->flags & XCONFIG_MODE_NVSYNC) + fprintf (cf, " -vsync"); + if (mlptr->flags & XCONFIG_MODE_INTERLACE) + fprintf (cf, " interlace"); + if (mlptr->flags & XCONFIG_MODE_CSYNC) + fprintf (cf, " composite"); + if (mlptr->flags & XCONFIG_MODE_PCSYNC) + fprintf (cf, " +csync"); + if (mlptr->flags & XCONFIG_MODE_NCSYNC) + fprintf (cf, " -csync"); + if (mlptr->flags & XCONFIG_MODE_DBLSCAN) + fprintf (cf, " doublescan"); + if (mlptr->flags & XCONFIG_MODE_HSKEW) + fprintf (cf, " hskew %d", mlptr->hskew); + if (mlptr->flags & XCONFIG_MODE_BCAST) + fprintf (cf, " bcast"); + fprintf (cf, "\n"); + } + xconfigPrintOptionList(cf, ptr->options, 1); + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigPrintModesSection (FILE * cf, XConfigModesPtr ptr) +{ + XConfigModeLinePtr mlptr; + + while (ptr) + { + fprintf (cf, "Section \"Modes\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + for (mlptr = ptr->modelines; mlptr; mlptr = mlptr->next) + { + fprintf (cf, " ModeLine \"%s\" %s ", + mlptr->identifier, mlptr->clock); + fprintf (cf, "%d %d %d %d %d %d %d %d", + mlptr->hdisplay, mlptr->hsyncstart, + mlptr->hsyncend, mlptr->htotal, + mlptr->vdisplay, mlptr->vsyncstart, + mlptr->vsyncend, mlptr->vtotal); + if (mlptr->flags & XCONFIG_MODE_PHSYNC) + fprintf (cf, " +hsync"); + if (mlptr->flags & XCONFIG_MODE_NHSYNC) + fprintf (cf, " -hsync"); + if (mlptr->flags & XCONFIG_MODE_PVSYNC) + fprintf (cf, " +vsync"); + if (mlptr->flags & XCONFIG_MODE_NVSYNC) + fprintf (cf, " -vsync"); + if (mlptr->flags & XCONFIG_MODE_INTERLACE) + fprintf (cf, " interlace"); + if (mlptr->flags & XCONFIG_MODE_CSYNC) + fprintf (cf, " composite"); + if (mlptr->flags & XCONFIG_MODE_PCSYNC) + fprintf (cf, " +csync"); + if (mlptr->flags & XCONFIG_MODE_NCSYNC) + fprintf (cf, " -csync"); + if (mlptr->flags & XCONFIG_MODE_DBLSCAN) + fprintf (cf, " doublescan"); + if (mlptr->flags & XCONFIG_MODE_HSKEW) + fprintf (cf, " hskew %d", mlptr->hskew); + if (mlptr->flags & XCONFIG_MODE_VSCAN) + fprintf (cf, " vscan %d", mlptr->vscan); + if (mlptr->flags & XCONFIG_MODE_BCAST) + fprintf (cf, " bcast"); + if (mlptr->comment) + fprintf (cf, "%s", mlptr->comment); + else + fprintf (cf, "\n"); + } + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigFreeMonitorList (XConfigMonitorPtr *ptr) +{ + XConfigMonitorPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->vendor); + TEST_FREE ((*ptr)->modelname); + TEST_FREE ((*ptr)->comment); + xconfigFreeOptionList (&((*ptr)->options)); + xconfigFreeModeLineList (&((*ptr)->modelines)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeModesList (XConfigModesPtr *ptr) +{ + XConfigModesPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->comment); + xconfigFreeModeLineList (&((*ptr)->modelines)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeModeLineList (XConfigModeLinePtr *ptr) +{ + XConfigModeLinePtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->comment); + TEST_FREE ((*ptr)->clock); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeModesLinkList (XConfigModesLinkPtr *ptr) +{ + XConfigModesLinkPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->modes_name); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +XConfigMonitorPtr +xconfigFindMonitor (const char *ident, XConfigMonitorPtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + +XConfigModesPtr +xconfigFindModes (const char *ident, XConfigModesPtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + +XConfigModeLinePtr +xconfigFindModeLine (const char *ident, XConfigModeLinePtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + +int +xconfigValidateMonitor (XConfigPtr p, XConfigScreenPtr screen) +{ + XConfigMonitorPtr monitor = screen->monitor; + XConfigModesLinkPtr modeslnk = monitor->modes_sections; + XConfigModesPtr modes; + while(modeslnk) + { + modes = xconfigFindModes (modeslnk->modes_name, p->modes); + if (!modes) + { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_MODES_MSG, + modeslnk->modes_name, screen->identifier); + return (FALSE); + } + modeslnk->modes = modes; + modeslnk = modeslnk->next; + } + return (TRUE); +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Pointer.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Pointer.c new file mode 100644 index 0000000..29e1c85 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Pointer.c @@ -0,0 +1,215 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec PointerTab[] = +{ + {PROTOCOL, "protocol"}, + {EMULATE3, "emulate3buttons"}, + {EM3TIMEOUT, "emulate3timeout"}, + {ENDSUBSECTION, "endsubsection"}, + {ENDSECTION, "endsection"}, + {PDEVICE, "device"}, + {PDEVICE, "port"}, + {BAUDRATE, "baudrate"}, + {SAMPLERATE, "samplerate"}, + {CLEARDTR, "cleardtr"}, + {CLEARRTS, "clearrts"}, + {CHORDMIDDLE, "chordmiddle"}, + {PRESOLUTION, "resolution"}, + {DEVICE_NAME, "devicename"}, + {ALWAYSCORE, "alwayscore"}, + {PBUTTONS, "buttons"}, + {ZAXISMAPPING, "zaxismapping"}, + {-1, ""}, +}; + +static XConfigSymTabRec ZMapTab[] = +{ + {XAXIS, "x"}, + {YAXIS, "y"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeInputList + +XConfigInputPtr +xconfigParsePointerSection (void) +{ + char *s, *s1, *s2; + int l; + int token; + PARSE_PROLOGUE (XConfigInputPtr, XConfigInputRec) + + while ((token = xconfigGetToken (PointerTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case PROTOCOL: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Protocol"); + xconfigAddNewOption(&ptr->options, "Protocol", val.str); + break; + case PDEVICE: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Device"); + xconfigAddNewOption(&ptr->options, "Device", val.str); + break; + case EMULATE3: + xconfigAddNewOption(&ptr->options, "Emulate3Buttons", NULL); + break; + case EM3TIMEOUT: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) + Error (POSITIVE_INT_MSG, "Emulate3Timeout"); + s = xconfigULongToString(val.num); + xconfigAddNewOption(&ptr->options, "Emulate3Timeout", s); + TEST_FREE(s); + break; + case CHORDMIDDLE: + xconfigAddNewOption(&ptr->options, "ChordMiddle", NULL); + break; + case PBUTTONS: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) + Error (POSITIVE_INT_MSG, "Buttons"); + s = xconfigULongToString(val.num); + xconfigAddNewOption(&ptr->options, "Buttons", s); + TEST_FREE(s); + break; + case BAUDRATE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) + Error (POSITIVE_INT_MSG, "BaudRate"); + s = xconfigULongToString(val.num); + xconfigAddNewOption(&ptr->options, "BaudRate", s); + TEST_FREE(s); + break; + case SAMPLERATE: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) + Error (POSITIVE_INT_MSG, "SampleRate"); + s = xconfigULongToString(val.num); + xconfigAddNewOption(&ptr->options, "SampleRate", s); + TEST_FREE(s); + break; + case PRESOLUTION: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || val.num < 0) + Error (POSITIVE_INT_MSG, "Resolution"); + s = xconfigULongToString(val.num); + xconfigAddNewOption(&ptr->options, "Resolution", s); + TEST_FREE(s); + break; + case CLEARDTR: + xconfigAddNewOption(&ptr->options, "ClearDTR", NULL); + break; + case CLEARRTS: + xconfigAddNewOption(&ptr->options, "ClearRTS", NULL); + break; + case ZAXISMAPPING: + switch (xconfigGetToken(ZMapTab)) { + case NUMBER: + if (val.num < 0) + Error (ZAXISMAPPING_MSG, NULL); + s1 = xconfigULongToString(val.num); + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER || + val.num < 0) + Error (ZAXISMAPPING_MSG, NULL); + s2 = xconfigULongToString(val.num); + l = strlen(s1) + 1 + strlen(s2) + 1; + s = malloc(l); + sprintf(s, "%s %s", s1, s2); + free(s1); + free(s2); + break; + case XAXIS: + s = xconfigStrdup("x"); + break; + case YAXIS: + s = xconfigStrdup("y"); + break; + default: + Error (ZAXISMAPPING_MSG, NULL); + break; + } + xconfigAddNewOption(&ptr->options, "ZAxisMapping", s); + TEST_FREE(s); + break; + case ALWAYSCORE: + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + ptr->identifier = xconfigStrdup(CONF_IMPLICIT_POINTER); + ptr->driver = xconfigStrdup("mouse"); + xconfigAddNewOption(&ptr->options, "CorePointer", NULL); + + return ptr; +} + +#undef CLEANUP + diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Read.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Read.c new file mode 100644 index 0000000..836360e --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Read.c @@ -0,0 +1,399 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec TopLevelTab[] = +{ + {SECTION, "section"}, + {-1, ""}, +}; + + +#define CLEANUP xconfigFreeConfig + +#define READ_HANDLE_RETURN(f,func) \ + if ((ptr->f=func) == NULL) { \ + xconfigFreeConfig(&ptr); \ + return XCONFIG_RETURN_PARSE_ERROR; \ + } + +#define READ_HANDLE_LIST(field,func,type) \ +{ \ + type p = func(); \ + if (p == NULL) { \ + xconfigFreeConfig(&ptr); \ + return XCONFIG_RETURN_PARSE_ERROR; \ + } else { \ + xconfigAddListItem((GenericListPtr *)(&ptr->field), \ + (GenericListPtr) p); \ + } \ +} + +#define READ_ERROR(a,b) \ + do { \ + xconfigErrorMsg(ParseErrorMsg, a, b); \ + xconfigFreeConfig(&ptr); \ + return XCONFIG_RETURN_PARSE_ERROR; \ + } while (0) + + + +/* + * xconfigReadConfigFile() - read the open XConfig file, returning the + * parsed data as XConfigPtr. + */ + +XConfigError xconfigReadConfigFile(XConfigPtr *configPtr) +{ + int token; + XConfigPtr ptr = NULL; + + *configPtr = NULL; + + ptr = xconfigAlloc(sizeof(XConfigRec)); + + while ((token = xconfigGetToken(TopLevelTab)) != EOF_TOKEN) { + + switch (token) { + + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + + case SECTION: + if (xconfigGetSubToken(&(ptr->comment)) != STRING) { + xconfigErrorMsg(ParseErrorMsg, QUOTE_MSG, "Section"); + xconfigFreeConfig(&ptr); + return XCONFIG_RETURN_PARSE_ERROR; + } + + xconfigSetSection(val.str); + + if (xconfigNameCompare(val.str, "files") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_RETURN(files, xconfigParseFilesSection()); + } + else if (xconfigNameCompare(val.str, "serverflags") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_RETURN(flags, xconfigParseFlagsSection()); + } + else if (xconfigNameCompare(val.str, "keyboard") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(inputs, xconfigParseKeyboardSection, + XConfigInputPtr); + } + else if (xconfigNameCompare(val.str, "pointer") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(inputs, xconfigParsePointerSection, + XConfigInputPtr); + } + else if (xconfigNameCompare(val.str, "videoadaptor") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(videoadaptors, + xconfigParseVideoAdaptorSection, + XConfigVideoAdaptorPtr); + } + else if (xconfigNameCompare(val.str, "device") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(devices, xconfigParseDeviceSection, + XConfigDevicePtr); + } + else if (xconfigNameCompare(val.str, "monitor") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(monitors, xconfigParseMonitorSection, + XConfigMonitorPtr); + } + else if (xconfigNameCompare(val.str, "modes") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(modes, xconfigParseModesSection, + XConfigModesPtr); + } + else if (xconfigNameCompare(val.str, "screen") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(screens, xconfigParseScreenSection, + XConfigScreenPtr); + } + else if (xconfigNameCompare(val.str, "inputdevice") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(inputs, xconfigParseInputSection, + XConfigInputPtr); + } + else if ((xconfigNameCompare(val.str, "inputclass") == 0)) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(inputclasses, xconfigParseInputClassSection, + XConfigInputClassPtr); + } + else if (xconfigNameCompare(val.str, "module") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_RETURN(modules, xconfigParseModuleSection()); + } + else if (xconfigNameCompare(val.str, "serverlayout") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(layouts, xconfigParseLayoutSection, + XConfigLayoutPtr); + } + else if (xconfigNameCompare(val.str, "vendor") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_LIST(vendors, xconfigParseVendorSection, + XConfigVendorPtr); + } + else if (xconfigNameCompare(val.str, "dri") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_RETURN(dri, xconfigParseDRISection()); + } + else if (xconfigNameCompare (val.str, "extensions") == 0) + { + free(val.str); + val.str = NULL; + READ_HANDLE_RETURN(extensions, xconfigParseExtensionsSection()); + } + else + { + READ_ERROR(INVALID_SECTION_MSG, xconfigTokenString()); + free(val.str); + val.str = NULL; + } + break; + + default: + READ_ERROR(INVALID_KEYWORD_MSG, xconfigTokenString()); + free(val.str); + val.str = NULL; + } + } + + if (xconfigValidateConfig(ptr)) { + ptr->filename = strdup(xconfigGetConfigFileName()); + *configPtr = ptr; + return XCONFIG_RETURN_SUCCESS; + } else { + xconfigFreeConfig(&ptr); + return XCONFIG_RETURN_VALIDATION_ERROR; + } +} + +#undef CLEANUP + + +/* + * This function resolves name references and reports errors if the named + * objects cannot be found. + */ + +int xconfigValidateConfig(XConfigPtr p) +{ + if (!xconfigValidateDevice(p)) + return FALSE; + if (!xconfigValidateScreen(p)) + return FALSE; + if (!xconfigValidateInput(p)) + return FALSE; + if (!xconfigValidateLayout(p)) + return FALSE; + + return(TRUE); +} + + + +/* + * This function fixes up any problems that it finds in the config, + * when possible. + */ + +int xconfigSanitizeConfig(XConfigPtr p, + const char *screenName, + GenerateOptions *gop) +{ + if (!xconfigSanitizeScreen(p)) + return FALSE; + + if (!xconfigSanitizeLayout(p, screenName, gop)) + return FALSE; + + return TRUE; +} + + + +/* + * adds an item to the end of the linked list. Any record whose first field + * is a GenericListRec can be cast to this type and used with this function. + */ +void xconfigAddListItem (GenericListPtr *pHead, GenericListPtr new) +{ + GenericListPtr p = *pHead; + GenericListPtr last = NULL; + + while (p) { + last = p; + p = p->next; + } + + if (last) { + last->next = new; + } else { + *pHead = new; + } +} + + +/* + * removes an item from the linked list (but does not delete it). Any record + * whose first field is a GenericListRec can be cast to this type and used + * with this function. + */ +void xconfigRemoveListItem (GenericListPtr *pHead, GenericListPtr item) +{ + GenericListPtr cur = *pHead; + GenericListPtr prev = NULL; + + while (cur) { + if (cur == item) { + if (prev) { + prev->next = item->next; + } else { + *pHead = item->next; + } + return; + } + prev = cur; + cur = cur->next; + } +} + + +/* + * Test if one chained list contains the other. + * In this case both list have the same endpoint (provided they don't loop) + */ +int +xconfigItemNotSublist(GenericListPtr list_1, GenericListPtr list_2) +{ + GenericListPtr p = list_1; + GenericListPtr last_1 = NULL, last_2 = NULL; + + while (p) { + last_1 = p; + p = p->next; + } + + p = list_2; + while (p) { + last_2 = p; + p = p->next; + } + + return (!(last_1 == last_2)); +} + +void +xconfigFreeConfig (XConfigPtr *p) +{ + if (p == NULL || *p == NULL) + return; + + xconfigFreeFiles (&((*p)->files)); + xconfigFreeModules (&((*p)->modules)); + xconfigFreeFlags (&((*p)->flags)); + xconfigFreeMonitorList (&((*p)->monitors)); + xconfigFreeModesList (&((*p)->modes)); + xconfigFreeVideoAdaptorList (&((*p)->videoadaptors)); + xconfigFreeDeviceList (&((*p)->devices)); + xconfigFreeScreenList (&((*p)->screens)); + xconfigFreeLayoutList (&((*p)->layouts)); + xconfigFreeInputList (&((*p)->inputs)); + xconfigFreeVendorList (&((*p)->vendors)); + xconfigFreeDRI (&((*p)->dri)); + TEST_FREE((*p)->comment); + + free (*p); + *p = NULL; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Scan.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Scan.c new file mode 100644 index 0000000..19473af --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Scan.c @@ -0,0 +1,1085 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + + +#include +#include +#include +#include +#include + +#if !defined(X_NOT_POSIX) +#if defined(_POSIX_SOURCE) +#include +#else +#define _POSIX_SOURCE +#include +#undef _POSIX_SOURCE +#endif /* _POSIX_SOURCE */ +#endif /* !X_NOT_POSIX */ +#if !defined(PATH_MAX) +#if defined(MAXPATHLEN) +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif /* MAXPATHLEN */ +#endif /* !PATH_MAX */ + +#if !defined(MAXHOSTNAMELEN) +#define MAXHOSTNAMELEN 32 +#endif /* !MAXHOSTNAMELEN */ + +#include "Configint.h" +#include "xf86tokens.h" + +#define CONFIG_BUF_LEN 1024 + +static int StringToToken (char *, XConfigSymTabRec *); + +static FILE *configFile = NULL; +static const char **builtinConfig = NULL; +static int builtinIndex = 0; +static int configPos = 0; /* current readers position */ +static char *configBuf, *configRBuf; /* buffer for lines */ +static int pushToken = LOCK_TOKEN; +static int eol_seen = 0; /* private state to handle comments */ +LexRec val; + +int configLineNo = 0; /* linenumber */ +char *configSection = NULL; /* name of current section being parsed */ +char *configPath; /* path to config file */ + + + + +static int xconfigIsAlpha(char c) +{ + return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))); +} + +static int xconfigIsDigit(char c) +{ + return ((c >= '0') && (c <= '9')); +} + +static int xconfigIsUpper(char c) +{ + return ((c >= 'A') && (c <= 'Z')); +} + +static char xconfigToLower(char c) +{ + if ((c >= 'A') && (c <= 'Z')) { + return c + ('a' - 'A'); + } else { + return c; + } +} + + +/* + * xconfigStrToUL -- + * + * A portable, but restricted, version of strtoul(). It only understands + * hex, octal, and decimal. But it's good enough for our needs. + */ + +static unsigned int xconfigStrToUL (char *str) +{ + int base = 10; + char *p = str; + unsigned int tot = 0; + + if (*p == '0') + { + p++; + if ((*p == 'x') || (*p == 'X')) + { + p++; + base = 16; + } + else + base = 8; + } + while (*p) + { + if ((*p >= '0') && (*p <= ((base == 8) ? '7' : '9'))) + { + tot = tot * base + (*p - '0'); + } + else if ((base == 16) && (*p >= 'a') && (*p <= 'f')) + { + tot = tot * base + 10 + (*p - 'a'); + } + else if ((base == 16) && (*p >= 'A') && (*p <= 'F')) + { + tot = tot * base + 10 + (*p - 'A'); + } + else + { + return (tot); + } + p++; + } + return (tot); +} + + +/* + * xconfigGetNextLine -- + * + * read from the configFile FILE stream until we encounter a new + * line; this is effectively just a big wrapper for fgets(3). + * + * xconfigGetToken() assumes that we will read up to the next + * newline; we need to grow configBuf and configRBuf as needed to + * support that. + */ + +static char *xconfigGetNextLine(void) +{ + static int configBufLen = CONFIG_BUF_LEN; + char *tmpConfigBuf, *tmpConfigRBuf; + int c, i, pos = 0, eolFound = 0; + char *ret = NULL; + + /* + * reallocate the string if it was grown last time (i.e., is no + * longer CONFIG_BUF_LEN); we malloc the new strings first, so + * that if either of the mallocs fail, we can fall back on the + * existing buffer allocations + */ + + if (configBufLen != CONFIG_BUF_LEN) { + + tmpConfigBuf = malloc(CONFIG_BUF_LEN); + tmpConfigRBuf = malloc(CONFIG_BUF_LEN); + + if (!tmpConfigBuf || !tmpConfigRBuf) { + + /* + * at least one of the mallocs failed; keep the old buffers + * and free any partial allocations + */ + + free(tmpConfigBuf); + free(tmpConfigRBuf); + + } else { + + /* + * malloc succeeded; free the old buffers and use the new + * buffers + */ + + configBufLen = CONFIG_BUF_LEN; + + free(configBuf); + free(configRBuf); + + configBuf = tmpConfigBuf; + configRBuf = tmpConfigRBuf; + } + } + + /* read in another block of chars */ + + do { + ret = fgets(configBuf + pos, configBufLen - pos - 1, configFile); + + if (!ret) break; + + /* search for EOL in the new block of chars */ + + for (i = pos; i < (configBufLen - 1); i++) { + c = configBuf[i]; + + if (c == '\0') break; + + if ((c == '\n') || (c == '\r')) { + eolFound = 1; + break; + } + } + + /* + * if we didn't find EOL, then grow the string and + * read in more + */ + + if (!eolFound) { + + tmpConfigBuf = realloc(configBuf, configBufLen + CONFIG_BUF_LEN); + tmpConfigRBuf = realloc(configRBuf, configBufLen + CONFIG_BUF_LEN); + + if (!tmpConfigBuf || !tmpConfigRBuf) { + + /* + * at least one of the reallocations failed; use the + * new allocation that succeeded, but we have to + * fallback to the previous configBufLen size and use + * the string we have, even though we don't have an + * EOL + */ + + if (tmpConfigBuf) configBuf = tmpConfigBuf; + if (tmpConfigRBuf) configRBuf = tmpConfigRBuf; + + break; + + } else { + + /* reallocation succeeded */ + + configBuf = tmpConfigBuf; + configRBuf = tmpConfigRBuf; + pos = i; + configBufLen += CONFIG_BUF_LEN; + } + } + + } while (!eolFound); + + return ret; +} + + + +/* + * xconfigGetToken -- + * Read next Token from the config file. Handle the global variable + * pushToken. + */ + +int xconfigGetToken (XConfigSymTabRec * tab) +{ + int c, i; + + /* + * First check whether pushToken has a different value than LOCK_TOKEN. + * In this case rBuf[] contains a valid STRING/TOKEN/NUMBER. But in the + * oth * case the next token must be read from the input. + */ + if (pushToken == EOF_TOKEN) + return (EOF_TOKEN); + else if (pushToken == LOCK_TOKEN) + { + /* + * eol_seen is only set for the first token after a newline. + */ + eol_seen = 0; + + c = configBuf[configPos]; + + /* + * Get start of next Token. EOF is handled, + * whitespaces are skipped. + */ + +again: + if (!c) + { + char *ret; + if (configFile) + ret = xconfigGetNextLine(); + else { + if (builtinConfig[builtinIndex] == NULL) + ret = NULL; + else { + ret = strncpy(configBuf, builtinConfig[builtinIndex], + CONFIG_BUF_LEN); + builtinIndex++; + } + } + if (ret == NULL) + { + return (pushToken = EOF_TOKEN); + } + configLineNo++; + configPos = 0; + eol_seen = 1; + } + + i = 0; + for (;;) { + c = configBuf[configPos++]; + configRBuf[i++] = c; + switch (c) { + case ' ': + case '\t': + case '\r': + continue; + case '\n': + i = 0; + continue; + } + break; + } + if (c == '\0') + goto again; + + if (c == '#') + { + do + { + configRBuf[i++] = (c = configBuf[configPos++]); + } + while ((c != '\n') && (c != '\r') && (c != '\0')); + configRBuf[i] = '\0'; + /* XXX no private copy. + * Use xconfigAddComment when setting a comment. + */ + val.str = configRBuf; + return (COMMENT); + } + + /* GJA -- handle '-' and ',' * Be careful: "-hsync" is a keyword. */ + else if ((c == ',') && !xconfigIsAlpha(configBuf[configPos])) + { + return COMMA; + } + else if ((c == '-') && !xconfigIsAlpha(configBuf[configPos])) + { + return DASH; + } + + /* + * Numbers are returned immediately ... + */ + if (xconfigIsDigit(c)) + { + int base; + + if (c == '0') + if ((configBuf[configPos] == 'x') || + (configBuf[configPos] == 'X')) + base = 16; + else + base = 8; + else + base = 10; + + configRBuf[0] = c; + i = 1; + while (xconfigIsDigit(c = configBuf[configPos++]) || + (c == '.') || (c == 'x') || (c == 'X') || + ((base == 16) && (((c >= 'a') && (c <= 'f')) || + ((c >= 'A') && (c <= 'F'))))) + configRBuf[i++] = c; + configPos--; /* GJA -- one too far */ + configRBuf[i] = '\0'; + val.num = xconfigStrToUL (configRBuf); + val.realnum = atof (configRBuf); + val.str = configRBuf; + return (NUMBER); + } + + /* + * All Strings START with a \" ... + */ + else if (c == '\"') + { + i = -1; + do + { + configRBuf[++i] = (c = configBuf[configPos++]); + } + while ((c != '\"') && (c != '\n') && (c != '\r') && (c != '\0')); + configRBuf[i] = '\0'; + val.str = malloc (strlen (configRBuf) + 1); + strcpy (val.str, configRBuf); /* private copy ! */ + return (STRING); + } + + /* + * ... and now we MUST have a valid token. The search is + * handled later along with the pushed tokens. + */ + else + { + configRBuf[0] = c; + i = 0; + do + { + configRBuf[++i] = (c = configBuf[configPos++]);; + } + while ((c != ' ') && + (c != '\t') && + (c != '\n') && + (c != '\r') && + (c != '\0') && + (c != '#')); + + --configPos; + configRBuf[i] = '\0'; + i = 0; + } + + } + else + { + + /* + * Here we deal with pushed tokens. Reinitialize pushToken again. If + * the pushed token was NUMBER || STRING return them again ... + */ + int temp = pushToken; + pushToken = LOCK_TOKEN; + + if (temp == COMMA || temp == DASH) + return (temp); + if (temp == NUMBER || temp == STRING) + return (temp); + } + + /* + * Joop, at last we have to lookup the token ... + */ + if (tab) + { + i = 0; + while (tab[i].token != -1) + if (xconfigNameCompare (configRBuf, tab[i].name) == 0) + return (tab[i].token); + else + i++; + } + + return (ERROR_TOKEN); /* Error catcher */ +} + +int xconfigGetSubToken (char **comment) +{ + int token; + + for (;;) { + token = xconfigGetToken(NULL); + if (token == COMMENT) { + if (comment) + *comment = xconfigAddComment(*comment, val.str); + } + else + return (token); + } + /*NOTREACHED*/ +} + +int xconfigGetSubTokenWithTab (char **comment, XConfigSymTabRec *tab) +{ + int token; + + for (;;) { + token = xconfigGetToken(tab); + if (token == COMMENT) { + if (comment) + *comment = xconfigAddComment(*comment, val.str); + } + else + return (token); + } + /*NOTREACHED*/ +} + +void xconfigUnGetToken (int token) +{ + pushToken = token; +} + +char *xconfigTokenString (void) +{ + return configRBuf; +} + +static int pathIsAbsolute(const char *path) +{ + if (path && path[0] == '/') + return 1; + return 0; +} + +/* A path is "safe" if it is relative and if it contains no ".." elements. */ +static int pathIsSafe(const char *path) +{ + if (pathIsAbsolute(path)) + return 0; + + /* Compare with ".." */ + if (!strcmp(path, "..")) + return 0; + + /* Look for leading "../" */ + if (!strncmp(path, "../", 3)) + return 0; + + /* Look for trailing "/.." */ + if ((strlen(path) > 3) && !strcmp(path + strlen(path) - 3, "/..")) + return 0; + + /* Look for "/../" */ + if (strstr(path, "/../")) + return 0; + + return 1; +} + +/* + * This function substitutes the following escape sequences: + * + * %A cmdline argument as an absolute path (must be absolute to match) + * %R cmdline argument as a relative path + * %S cmdline argument as a "safe" path (relative, and no ".." elements) + * %X default config file name ("XF86Config") + * %H hostname + * %E config file environment ($XF86CONFIG) as an absolute path + * %F config file environment ($XF86CONFIG) as a relative path + * %G config file environment ($XF86CONFIG) as a safe path + * %P projroot + * %M major version number + * %% % + * %& UNIXOS2 only: prepend X11ROOT env var + */ + +#ifndef XCONFIGFILE +#define XCONFIGFILE "xorg.conf" +#endif +#ifndef PROJECTROOT +#define PROJECTROOT "/usr/X11R6" +#endif +#ifndef XCONFENV +#define XCONFENV "XF86CONFIG" +#endif +#define XFREE86CFGFILE "XF86Config" +#ifndef X_VERSION_MAJOR +#ifdef XVERSION +#if XVERSION > 40000000 +#define X_VERSION_MAJOR (XVERSION / 10000000) +#else +#define X_VERSION_MAJOR (XVERSION / 1000) +#endif +#else +#define X_VERSION_MAJOR 4 +#endif +#endif + +#define BAIL_OUT do { \ + free(result); \ + return NULL; \ + } while (0) + +#define CHECK_LENGTH do { \ + if (l > PATH_MAX) { \ + BAIL_OUT; \ + } \ + } while (0) + +#define APPEND_STR(s) do { \ + if (strlen(s) + l > PATH_MAX) { \ + BAIL_OUT; \ + } else { \ + strcpy(result + l, s); \ + l += strlen(s); \ + } \ + } while (0) + +static char *DoSubstitution(const char *template, + const char *cmdline, + const char *projroot, + int *cmdlineUsed, int *envUsed, char *XConfigFile) +{ + char *result; + int i, l; + static const char *env = NULL; + static char *hostname = NULL; + static char majorvers[3] = ""; + + if (!template) + return NULL; + + if (cmdlineUsed) + *cmdlineUsed = 0; + if (envUsed) + *envUsed = 0; + + result = malloc(PATH_MAX + 1); + l = 0; + for (i = 0; template[i]; i++) { + if (template[i] != '%') { + result[l++] = template[i]; + CHECK_LENGTH; + } else { + switch (template[++i]) { + case 'A': + if (cmdline && pathIsAbsolute(cmdline)) { + APPEND_STR(cmdline); + if (cmdlineUsed) + *cmdlineUsed = 1; + } else + BAIL_OUT; + break; + case 'R': + if (cmdline && !pathIsAbsolute(cmdline)) { + APPEND_STR(cmdline); + if (cmdlineUsed) + *cmdlineUsed = 1; + } else + BAIL_OUT; + break; + case 'S': + if (cmdline && pathIsSafe(cmdline)) { + APPEND_STR(cmdline); + if (cmdlineUsed) + *cmdlineUsed = 1; + } else + BAIL_OUT; + break; + case 'X': + APPEND_STR(XConfigFile); + break; + case 'H': + if (!hostname) { + if ((hostname = malloc(MAXHOSTNAMELEN + 1))) { + if (gethostname(hostname, MAXHOSTNAMELEN) == 0) { + hostname[MAXHOSTNAMELEN] = '\0'; + } else { + free(hostname); + hostname = NULL; + } + } + } + if (hostname) + APPEND_STR(hostname); + break; + case 'E': + if (!env) + env = getenv(XCONFENV); + if (env && pathIsAbsolute(env)) { + APPEND_STR(env); + if (envUsed) + *envUsed = 1; + } else + BAIL_OUT; + break; + case 'F': + if (!env) + env = getenv(XCONFENV); + if (env && !pathIsAbsolute(env)) { + APPEND_STR(env); + if (envUsed) + *envUsed = 1; + } else + BAIL_OUT; + break; + case 'G': + if (!env) + env = getenv(XCONFENV); + if (env && pathIsSafe(env)) { + APPEND_STR(env); + if (envUsed) + *envUsed = 1; + } else + BAIL_OUT; + break; + case 'P': + if (projroot && pathIsAbsolute(projroot)) + APPEND_STR(projroot); + else + BAIL_OUT; + break; + case 'M': + if (!majorvers[0]) { + sprintf(majorvers, "%d", X_VERSION_MAJOR); + } + APPEND_STR(majorvers); + break; + case '%': + result[l++] = '%'; + CHECK_LENGTH; + break; + default: + xconfigErrorMsg(InternalErrorMsg, + "invalid escape %%%c found in path template\n", + template[i]); + BAIL_OUT; + break; + } + } + } + return result; +} + +/* + * xconfigOpenConfigFile -- + * + * This function takes a config file search path (optional), a + * command-line specified file name (optional) and the ProjectRoot + * path (optional) and locates and opens a config file based on that + * information. If a command-line file name is specified, then this + * function fails if none of the located files. + * + * The return value is a pointer to the actual name of the file that + * was opened. When no file is found, the return value is NULL. + * + * The escape sequences allowed in the search path are defined above. + * + */ + + +/* + * __root_configpath[] - this is the XconfigConfig search path used by + * XFree86 when the server runs as root. + */ + +static const char __root_configpath[] = +"%A," /* */ +"%R," /* (as relative path) */ +"/etc/X11/%R," /* /etc/X11/ */ +"%P/etc/X11/%R," /* /usr/X11R6/etc/X11/ */ +"%E," /* $XF86CONFIG */ +"%F," /* $XF86CONFIG (as relative path) */ +"/etc/X11/%F," /* /etc/X11/$XF86CONFIG */ +"%P/etc/X11/%F," /* /usr/X11R6/etc/X11/$XF86CONFIG */ +"/etc/X11/%X-%M," /* /etc/X11/XF86Config-4 */ +"/etc/X11/%X," /* /etc/X11/XF86Config */ +"/etc/%X," /* /etc/XF86Config */ +"%P/etc/X11/%X.%H," /* /usr/X11R6/etc/X11/XF86Config. */ +"%P/etc/X11/%X-%M," /* /usr/X11R6/etc/X11/XF86Config-4 */ +"%P/etc/X11/%X," /* /usr/X11R6/etc/X11/XF86Config */ +"%P/lib/X11/%X.%H," /* /usr/X11R6/lib/X11/XF86Config. */ +"%P/lib/X11/%X-%M," /* /usr/X11R6/lib/X11/XF86Config-4 */ +"%P/lib/X11/%X"; /* /usr/X11R6/lib/X11/XF86Config */ + + + +/* + * __user_configpath[] - this is the XF86Config search path used by + * XFree86 when the server runs as a normal user + */ + +static const char __user_configpath[] = +"%A," /* XXX */ +"%R," /* (as relative path) XXX */ +"/etc/X11/%S," /* /etc/X11/ */ +"%P/etc/X11/%S," /* /usr/X11R6/etc/X11/ */ +"/etc/X11/%G," /* /etc/X11/$XF86CONFIG */ +"%P/etc/X11/%G," /* /usr/X11R6/etc/X11/$XF86CONFIG */ +"/etc/X11/%X-%M," /* /etc/X11/XF86Config-4 */ +"/etc/X11/%X," /* /etc/X11/XF86Config */ +"/etc/%X," /* /etc/XF86Config */ +"%P/etc/X11/%X.%H," /* /usr/X11R6/etc/X11/XF86Config. */ +"%P/etc/X11/%X-%M," /* /usr/X11R6/etc/X11/XF86Config-4 */ +"%P/etc/X11/%X," /* /usr/X11R6/etc/X11/XF86Config */ +"%P/lib/X11/%X.%H," /* /usr/X11R6/lib/X11/XF86Config. */ +"%P/lib/X11/%X-%M," /* /usr/X11R6/lib/X11/XF86Config-4 */ +"%P/lib/X11/%X"; /* /usr/X11R6/lib/X11/XF86Config */ + + + +const char *xconfigOpenConfigFile(const char *cmdline, const char *projroot) +{ + const char *searchpath; + char *pathcopy; + const char *template; + int cmdlineUsed = 0; + + configFile = NULL; + configPos = 0; /* current readers position */ + configLineNo = 0; /* linenumber */ + pushToken = LOCK_TOKEN; + + /* + * select the search path: XFree86 uses a slightly different path + * depending on whether the user is root + */ + + if (getuid() == 0) { + searchpath = __root_configpath; + } else { + searchpath = __user_configpath; + } + + if (!projroot) projroot = PROJECTROOT; + + pathcopy = strdup(searchpath); + + template = strtok(pathcopy, ","); + + /* First, search for a config file. */ + while (template && !configFile) { + if ((configPath = DoSubstitution(template, cmdline, projroot, + &cmdlineUsed, NULL, XCONFIGFILE))) { + if ((configFile = fopen(configPath, "r")) != 0) { + if (cmdline && !cmdlineUsed) { + fclose(configFile); + configFile = NULL; + } + } + } + if (configPath && !configFile) { + free(configPath); + configPath = NULL; + } + template = strtok(NULL, ","); + } + + /* Then search for fallback */ + if (!configFile) { + strcpy(pathcopy, searchpath); + template = strtok(pathcopy, ","); + + while (template && !configFile) { + if ((configPath = DoSubstitution(template, cmdline, projroot, + &cmdlineUsed, NULL, + XFREE86CFGFILE))) { + if ((configFile = fopen(configPath, "r")) != 0) { + if (cmdline && !cmdlineUsed) { + fclose(configFile); + configFile = NULL; + } + } + } + if (configPath && !configFile) { + free(configPath); + configPath = NULL; + } + template = strtok(NULL, ","); + } + } + + free(pathcopy); + + if (!configFile) { + return NULL; + } + + configBuf = malloc(CONFIG_BUF_LEN); + configRBuf = malloc(CONFIG_BUF_LEN); + configBuf[0] = '\0'; + + return configPath; +} + +void xconfigCloseConfigFile (void) +{ + free (configPath); + configPath = NULL; + free (configRBuf); + configRBuf = NULL; + free (configBuf); + configBuf = NULL; + + if (configFile) { + fclose (configFile); + configFile = NULL; + } else { + builtinConfig = NULL; + builtinIndex = 0; + } +} + + +char *xconfigGetConfigFileName(void) +{ + return configPath; +} + + +void +xconfigSetSection (char *section) +{ + if (configSection) + free(configSection); + configSection = malloc(strlen (section) + 1); + strcpy (configSection, section); +} + +/* + * xconfigGetToken -- + * Lookup a string if it is actually a token in disguise. + */ + + +char * +xconfigAddComment(char *cur, char *add) +{ + char *str; + int len, curlen, iscomment, hasnewline = 0, endnewline; + + if (add == NULL || add[0] == '\0') + return (cur); + + if (cur) { + curlen = strlen(cur); + if (curlen) + hasnewline = cur[curlen - 1] == '\n'; + eol_seen = 0; + } + else + curlen = 0; + + str = add; + iscomment = 0; + while (*str) { + if (*str != ' ' && *str != '\t') + break; + ++str; + } + iscomment = (*str == '#'); + + len = strlen(add); + endnewline = add[len - 1] == '\n'; + len += 1 + iscomment + (!hasnewline) + (!endnewline) + eol_seen; + + if ((str = realloc(cur, len + curlen)) == NULL) + return (cur); + + cur = str; + + if (eol_seen || (curlen && !hasnewline)) + cur[curlen++] = '\n'; + if (!iscomment) + cur[curlen++] = '#'; + strcpy(cur + curlen, add); + if (!endnewline) + strcat(cur, "\n"); + + return (cur); +} + +int +xconfigGetStringToken (XConfigSymTabRec * tab) +{ + return StringToToken (val.str, tab); +} + +static int +StringToToken (char *str, XConfigSymTabRec * tab) +{ + int i; + + for (i = 0; tab[i].token != -1; i++) + { + if (!xconfigNameCompare (tab[i].name, str)) + return tab[i].token; + } + return (ERROR_TOKEN); +} + + +/* + * Compare two names. The characters '_', ' ', and '\t' are ignored + * in the comparison. + */ +int +xconfigNameCompare (const char *s1, const char *s2) +{ + char c1, c2; + + if (!s1 || *s1 == 0) { + if (!s2 || *s2 == 0) + return (0); + else + return (1); + } + + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + c1 = (xconfigIsUpper(*s1) ? xconfigToLower(*s1) : *s1); + c2 = (xconfigIsUpper(*s2) ? xconfigToLower(*s2) : *s2); + while (c1 == c2) + { + if (c1 == '\0') + return (0); + s1++; + s2++; + while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') + s1++; + while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') + s2++; + c1 = (xconfigIsUpper(*s1) ? xconfigToLower(*s1) : *s1); + c2 = (xconfigIsUpper(*s2) ? xconfigToLower(*s2) : *s2); + } + return (c1 - c2); +} + +/* + * Compare two modelines. The modeline identifiers and comments are + * ignored in the comparison. + */ +int +xconfigModelineCompare(XConfigModeLinePtr m1, XConfigModeLinePtr m2) +{ + if (!m1 && !m2) + return (0); + + if (!m1 || !m2) + return (1); + + if (m1->clock != m2->clock && + m1->hdisplay != m2->hdisplay && + m1->hsyncstart != m2->hsyncstart && + m1->hsyncend != m2->hsyncend && + m1->htotal != m2->htotal && + m1->vdisplay != m2->vdisplay && + m1->vsyncstart != m2->vsyncstart && + m1->vsyncend != m2->vsyncend && + m1->vtotal != m2->vtotal && + m1->vscan != m2->vscan && + m1->flags != m2->flags && + m1->hskew != m2->hskew) + return (1); + return (0); +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Screen.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Screen.c new file mode 100644 index 0000000..ce6b299 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Screen.c @@ -0,0 +1,734 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec DisplayTab[] = +{ + {ENDSUBSECTION, "endsubsection"}, + {MODES, "modes"}, + {VIEWPORT, "viewport"}, + {VIRTUAL, "virtual"}, + {VISUAL, "visual"}, + {BLACK_TOK, "black"}, + {WHITE_TOK, "white"}, + {DEPTH, "depth"}, + {BPP, "fbbpp"}, + {WEIGHT, "weight"}, + {OPTION, "option"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeDisplayList + +static int addImpliedScreen(XConfigPtr config); + +XConfigDisplayPtr +xconfigParseDisplaySubSection (void) +{ + int token; + PARSE_PROLOGUE (XConfigDisplayPtr, XConfigDisplayRec) + + ptr->black.red = ptr->black.green = ptr->black.blue = -1; + ptr->white.red = ptr->white.green = ptr->white.blue = -1; + ptr->frameX0 = ptr->frameY0 = -1; + while ((token = xconfigGetToken (DisplayTab)) != ENDSUBSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case VIEWPORT: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (VIEWPORT_MSG, NULL); + ptr->frameX0 = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (VIEWPORT_MSG, NULL); + ptr->frameY0 = val.num; + break; + case VIRTUAL: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (VIRTUAL_MSG, NULL); + ptr->virtualX = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (VIRTUAL_MSG, NULL); + ptr->virtualY = val.num; + break; + case DEPTH: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "Display"); + ptr->depth = val.num; + break; + case BPP: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "Display"); + ptr->bpp = val.num; + break; + case VISUAL: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Display"); + ptr->visual = val.str; + break; + case WEIGHT: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (WEIGHT_MSG, NULL); + ptr->weight.red = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (WEIGHT_MSG, NULL); + ptr->weight.green = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (WEIGHT_MSG, NULL); + ptr->weight.blue = val.num; + break; + case BLACK_TOK: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (BLACK_MSG, NULL); + ptr->black.red = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (BLACK_MSG, NULL); + ptr->black.green = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (BLACK_MSG, NULL); + ptr->black.blue = val.num; + break; + case WHITE_TOK: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (WHITE_MSG, NULL); + ptr->white.red = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (WHITE_MSG, NULL); + ptr->white.green = val.num; + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (WHITE_MSG, NULL); + ptr->white.blue = val.num; + break; + case MODES: + { + XConfigModePtr mptr; + + while ((token = + xconfigGetSubTokenWithTab(&(ptr->comment), + DisplayTab)) == STRING) + { + mptr = calloc (1, sizeof (XConfigModeRec)); + mptr->mode_name = val.str; + mptr->next = NULL; + xconfigAddListItem((GenericListPtr *)(&ptr->modes), + (GenericListPtr) mptr); + } + xconfigUnGetToken (token); + } + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +static XConfigSymTabRec ScreenTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {OBSDRIVER, "driver"}, + {MDEVICE, "device"}, + {MONITOR, "monitor"}, + {VIDEOADAPTOR, "videoadaptor"}, + {SCREENNO, "screenno"}, + {SUBSECTION, "subsection"}, + {DEFAULTDEPTH, "defaultcolordepth"}, + {DEFAULTDEPTH, "defaultdepth"}, + {DEFAULTBPP, "defaultbpp"}, + {DEFAULTFBBPP, "defaultfbbpp"}, + {OPTION, "option"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeScreenList +XConfigScreenPtr +xconfigParseScreenSection (void) +{ + int has_ident = FALSE; + int has_driver= FALSE; + int token; + + PARSE_PROLOGUE (XConfigScreenPtr, XConfigScreenRec) + + while ((token = xconfigGetToken (ScreenTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + ptr->identifier = val.str; + if (has_ident || has_driver) + Error (ONLY_ONE_MSG,"Identifier or Driver"); + has_ident = TRUE; + break; + case OBSDRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Driver"); + ptr->obsolete_driver = val.str; + if (has_ident || has_driver) + Error (ONLY_ONE_MSG,"Identifier or Driver"); + has_driver = TRUE; + break; + case DEFAULTDEPTH: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "DefaultDepth"); + ptr->defaultdepth = val.num; + break; + case DEFAULTBPP: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "DefaultBPP"); + ptr->defaultbpp = val.num; + break; + case DEFAULTFBBPP: + if (xconfigGetSubToken (&(ptr->comment)) != NUMBER) + Error (NUMBER_MSG, "DefaultFbBPP"); + ptr->defaultfbbpp = val.num; + break; + case MDEVICE: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Device"); + ptr->device_name = val.str; + break; + case MONITOR: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Monitor"); + ptr->monitor_name = val.str; + break; + case VIDEOADAPTOR: + { + XConfigAdaptorLinkPtr aptr; + + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "VideoAdaptor"); + + /* Don't allow duplicates */ + for (aptr = ptr->adaptors; aptr; + aptr = (XConfigAdaptorLinkPtr) aptr->next) + if (xconfigNameCompare (val.str, aptr->adaptor_name) == 0) + break; + + if (aptr == NULL) + { + aptr = calloc (1, sizeof (XConfigAdaptorLinkRec)); + aptr->next = NULL; + aptr->adaptor_name = val.str; + xconfigAddListItem ((GenericListPtr *)(&ptr->adaptors), + (GenericListPtr) aptr); + } + } + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case SUBSECTION: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "SubSection"); + { + free(val.str); + HANDLE_LIST (displays, xconfigParseDisplaySubSection, + XConfigDisplayPtr); + } + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + if (!has_ident && !has_driver) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +void +xconfigPrintScreenSection (FILE * cf, XConfigScreenPtr ptr) +{ + XConfigAdaptorLinkPtr aptr; + XConfigDisplayPtr dptr; + XConfigModePtr mptr; + + while (ptr) + { + fprintf (cf, "Section \"Screen\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + if (ptr->obsolete_driver) + fprintf (cf, " Driver \"%s\"\n", ptr->obsolete_driver); + if (ptr->device_name) + fprintf (cf, " Device \"%s\"\n", ptr->device_name); + if (ptr->monitor_name) + fprintf (cf, " Monitor \"%s\"\n", ptr->monitor_name); + if (ptr->defaultdepth) + fprintf (cf, " DefaultDepth %d\n", + ptr->defaultdepth); + if (ptr->defaultbpp) + fprintf (cf, " DefaultBPP %d\n", + ptr->defaultbpp); + if (ptr->defaultfbbpp) + fprintf (cf, " DefaultFbBPP %d\n", + ptr->defaultfbbpp); + xconfigPrintOptionList(cf, ptr->options, 1); + for (aptr = ptr->adaptors; aptr; aptr = aptr->next) + { + fprintf (cf, " VideoAdaptor \"%s\"\n", aptr->adaptor_name); + } + for (dptr = ptr->displays; dptr; dptr = dptr->next) + { + fprintf (cf, " SubSection \"Display\"\n"); + if (dptr->comment) + fprintf (cf, "%s", dptr->comment); + if (dptr->frameX0 >= 0 || dptr->frameY0 >= 0) + { + fprintf (cf, " Viewport %d %d\n", + dptr->frameX0, dptr->frameY0); + } + if (dptr->virtualX != 0 || dptr->virtualY != 0) + { + fprintf (cf, " Virtual %d %d\n", + dptr->virtualX, dptr->virtualY); + } + if (dptr->depth) + { + fprintf (cf, " Depth %d\n", dptr->depth); + } + if (dptr->bpp) + { + fprintf (cf, " FbBPP %d\n", dptr->bpp); + } + if (dptr->visual) + { + fprintf (cf, " Visual \"%s\"\n", dptr->visual); + } + if (dptr->weight.red != 0) + { + fprintf (cf, " Weight %d %d %d\n", + dptr->weight.red, dptr->weight.green, dptr->weight.blue); + } + if (dptr->black.red != -1) + { + fprintf (cf, " Black 0x%04x 0x%04x 0x%04x\n", + dptr->black.red, dptr->black.green, dptr->black.blue); + } + if (dptr->white.red != -1) + { + fprintf (cf, " White 0x%04x 0x%04x 0x%04x\n", + dptr->white.red, dptr->white.green, dptr->white.blue); + } + if (dptr->modes) + { + fprintf (cf, " Modes "); + } + for (mptr = dptr->modes; mptr; mptr = mptr->next) + { + fprintf (cf, " \"%s\"", mptr->mode_name); + } + if (dptr->modes) + { + fprintf (cf, "\n"); + } + xconfigPrintOptionList(cf, dptr->options, 2); + fprintf (cf, " EndSubSection\n"); + } + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } + +} + +void +xconfigFreeScreenList (XConfigScreenPtr *ptr) +{ + XConfigScreenPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->monitor_name); + TEST_FREE ((*ptr)->device_name); + TEST_FREE ((*ptr)->comment); + xconfigFreeOptionList (&((*ptr)->options)); + xconfigFreeAdaptorLinkList (&((*ptr)->adaptors)); + xconfigFreeDisplayList (&((*ptr)->displays)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeAdaptorLinkList (XConfigAdaptorLinkPtr *ptr) +{ + XConfigAdaptorLinkPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->adaptor_name); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeDisplayList (XConfigDisplayPtr *ptr) +{ + XConfigDisplayPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + xconfigFreeModeList (&((*ptr)->modes)); + xconfigFreeOptionList (&((*ptr)->options)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeModeList (XConfigModePtr *ptr) +{ + XConfigModePtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->mode_name); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +int +xconfigValidateScreen (XConfigPtr p) +{ + XConfigScreenPtr screen = p->screens; + XConfigMonitorPtr monitor; + XConfigDevicePtr device; + XConfigAdaptorLinkPtr adaptor; + + /* + * if we do not have a screen, just return TRUE; we'll add a + * screen later during the Sanitize step + */ + + if (!screen) return TRUE; + + while (screen) + { + if (screen->obsolete_driver && !screen->identifier) + screen->identifier = screen->obsolete_driver; + + monitor = xconfigFindMonitor (screen->monitor_name, p->monitors); + if (screen->monitor_name) + { + if (!monitor) + { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_MONITOR_MSG, + screen->monitor_name, screen->identifier); + return (FALSE); + } + else + { + screen->monitor = monitor; + if (!xconfigValidateMonitor(p, screen)) + return (FALSE); + } + } + + device = xconfigFindDevice (screen->device_name, p->devices); + if (!device) + { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_DEVICE_MSG, + screen->device_name, screen->identifier); + return (FALSE); + } + else + screen->device = device; + + adaptor = screen->adaptors; + while (adaptor) { + adaptor->adaptor = xconfigFindVideoAdaptor(adaptor->adaptor_name, + p->videoadaptors); + if (!adaptor->adaptor) { + xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_ADAPTOR_MSG, + adaptor->adaptor_name, + screen->identifier); + return (FALSE); + } else if (adaptor->adaptor->fwdref) { + xconfigErrorMsg(ValidationErrorMsg, ADAPTOR_REF_TWICE_MSG, + adaptor->adaptor_name, + adaptor->adaptor->fwdref); + return (FALSE); + } + + adaptor->adaptor->fwdref = xconfigStrdup(screen->identifier); + adaptor = adaptor->next; + } + + screen = screen->next; + } + + return (TRUE); +} + +int xconfigSanitizeScreen(XConfigPtr p) +{ + XConfigScreenPtr screen = p->screens; + XConfigMonitorPtr monitor; + + if (!addImpliedScreen(p)) { + return FALSE; + } + + while (screen) { + + /* + * if no monitor for this screen (either the monitor name, or + * the actual monitor pointer), find a monitor: resolve + * discrepancies between screen->monitor_name and + * screen->monitor; otherwise use the first monitor in the + * config; if we still don't have a monitor, add a new one + */ + + if (!screen->monitor_name || !screen->monitor) { + + monitor = NULL; + + if (!monitor && screen->monitor) { + monitor = screen->monitor; + } + + if (!monitor && screen->monitor_name) { + monitor = xconfigFindMonitor(screen->monitor_name, + p->monitors); + } + + if (!monitor && p->monitors) { + monitor = p->monitors; + } + + if (!monitor) { + monitor = xconfigAddMonitor(p, 0); + } + + if (monitor) { + screen->monitor = monitor; + + if (screen->monitor_name) { + free(screen->monitor_name); + } + + screen->monitor_name = xconfigStrdup(monitor->identifier); + + if (!xconfigValidateMonitor(p, screen)) { + return FALSE; + } + } + } + + screen = screen->next; + } + + return TRUE; +} + + + +XConfigScreenPtr +xconfigFindScreen (const char *ident, XConfigScreenPtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + +XConfigModePtr +xconfigFindMode (const char *name, XConfigModePtr p) +{ + while (p) + { + if (xconfigNameCompare (name, p->mode_name) == 0) + return (p); + + p = p->next; + } + return (NULL); +} + +void +xconfigAddMode(XConfigModePtr *pHead, const char *name) +{ + XConfigModePtr mode; + + mode = xconfigAlloc(sizeof(XConfigModeRec)); + mode->mode_name = xconfigStrdup(name); + + mode->next = *pHead; + *pHead = mode; +} + + +void +xconfigRemoveMode(XConfigModePtr *pHead, const char *name) +{ + XConfigModePtr p = *pHead; + XConfigModePtr last = NULL; + + while (p) { + if (xconfigNameCompare(p->mode_name, name) == 0) { + if (last) { + last->next = p->next; + } else { + *pHead = p->next; + } + free(p->mode_name); + free(p); + return; + } + last = p; + p = p->next; + } +} + + +static int addImpliedScreen(XConfigPtr config) +{ + XConfigScreenPtr screen; + XConfigDevicePtr device; + XConfigMonitorPtr monitor; + + if (config->screens) return TRUE; + + xconfigErrorMsg(WarnMsg, "No Screen specified, constructing implicit " + "screen section.\n"); + + /* allocate the new screen section */ + + screen = calloc(1, sizeof(XConfigScreenRec)); + if (!screen) return FALSE; + + screen->identifier = xconfigStrdup("Default Screen"); + + /* + * Use the first device section if there is one. + */ + if (config->devices) { + device = config->devices; + screen->device_name = xconfigStrdup(device->identifier); + screen->device = device; + } + + /* + * Use the first monitor section if there is one. + */ + if (config->monitors) { + monitor = config->monitors; + screen->monitor_name = xconfigStrdup(monitor->identifier); + screen->monitor = monitor; + } + + config->screens = screen; + + return TRUE; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Util.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Util.c new file mode 100644 index 0000000..c9d1bcd --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Util.c @@ -0,0 +1,180 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2005 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * Util.c + */ + +#include +#include +#include +#include + +#include "xf86Parser.h" +#include "Configint.h" + +void *xconfigAlloc(size_t size) +{ + void *m = malloc(size); + + if (!m) { + fprintf(stderr, "memory allocation failure (%s)! \n", strerror(errno)); + exit(1); + } + memset((char *) m, 0, size); + return m; + +} /* xconfigAlloc() */ + + +/* + * xconfigStrdup() - wrapper for strdup() that checks the return + * value; if an error occurs, an error is printed to stderr and exit + * is called -- this function will only return on success. + */ + +char *xconfigStrdup(const char *s) +{ + char *m; + + if (!s) return NULL; + + m = strdup(s); + + if (!m) { + fprintf(stderr, "memory allocation failure during strdup (%s)! \n", + strerror(errno)); + exit(1); + } + return m; + +} /* xconfigStrdup() */ + + +/* + * xconfigStrcat() - allocate a new string, copying all given strings + * into it. taken from glib + */ + +char *xconfigStrcat(const char *str, ...) +{ + unsigned int l; + va_list args; + char *s; + char *concat; + + l = 1 + strlen(str); + va_start(args, str); + s = va_arg(args, char *); + + while (s) { + l += strlen(s); + s = va_arg(args, char *); + } + va_end(args); + + concat = xconfigAlloc(l); + concat[0] = 0; + + strcat(concat, str); + va_start(args, str); + s = va_arg(args, char *); + while (s) { + strcat(concat, s); + s = va_arg(args, char *); + } + va_end(args); + + return concat; + +} /* xconfigStrcat() */ + + + + + + +#define NV_FMT_BUF_LEN 64 + +extern int configLineNo; +extern char *configSection; +extern char *configPath; + +void xconfigErrorMsg(MsgType t, char *fmt, ...) +{ + va_list ap; + int len, current_len = NV_FMT_BUF_LEN; + char *b, *pre = NULL, *msg; + char scratch[64]; + + b = xconfigAlloc(current_len); + + while (1) { + va_start(ap, fmt); + len = vsnprintf(b, current_len, fmt, ap); + va_end(ap); + + if ((len > -1) && (len < current_len)) { + break; + } else if (len > -1) { + current_len = len + 1; + } else { + current_len += NV_FMT_BUF_LEN; + } + + free(b); + b = xconfigAlloc(current_len); + } + + switch (t) { + case ParseErrorMsg: + sprintf(scratch, "%d", configLineNo); + pre = xconfigStrcat("Parse error on line ", scratch, " of section ", + configSection, " in file ", configPath, ".\n", NULL); + break; + case ParseWarningMsg: + sprintf(scratch, "%d", configLineNo); + pre = xconfigStrcat("Parse warning on line ", scratch, " of section ", + configSection, " in file ", configPath, ".\n", NULL); + break; + case ValidationErrorMsg: + pre = xconfigStrcat("Data incomplete in file ", configPath, ".\n", NULL); + break; + case InternalErrorMsg: break; + case WriteErrorMsg: break; + case WarnMsg: break; + case ErrorMsg: break; + case DebugMsg: break; + case UnknownMsg: break; + } + + if (pre) { + msg = xconfigStrcat(pre, b, NULL); + } else { + msg = strdup(b); + } + + /* call back into the host to print the message */ + + xconfigPrint(t, msg); + + + free(b); + free(msg); + if (pre) free(pre); +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Vendor.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Vendor.c new file mode 100644 index 0000000..ba0ca09 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Vendor.c @@ -0,0 +1,250 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec VendorSubTab[] = +{ + {ENDSUBSECTION, "endsubsection"}, + {IDENTIFIER, "identifier"}, + {OPTION, "option"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeVendorSubList + +XConfigVendSubPtr +xconfigParseVendorSubSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigVendSubPtr, XConfigVendSubRec) + + while ((token = xconfigGetToken (VendorSubTab)) != ENDSUBSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment))) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +static XConfigSymTabRec VendorTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {OPTION, "option"}, + {SUBSECTION, "subsection"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeVendorList + +XConfigVendorPtr +xconfigParseVendorSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigVendorPtr, XConfigVendorRec) + + while ((token = xconfigGetToken (VendorTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case SUBSECTION: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "SubSection"); + { + HANDLE_LIST (subs, xconfigParseVendorSubSection, + XConfigVendSubPtr); + } + break; + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +#undef CLEANUP + +void +xconfigPrintVendorSection (FILE * cf, XConfigVendorPtr ptr) +{ + XConfigVendSubPtr pptr; + + while (ptr) + { + fprintf (cf, "Section \"Vendor\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + + xconfigPrintOptionList(cf, ptr->options, 1); + for (pptr = ptr->subs; pptr; pptr = pptr->next) + { + fprintf (cf, " SubSection \"Vendor\"\n"); + if (pptr->comment) + fprintf (cf, "%s", pptr->comment); + if (pptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", pptr->identifier); + xconfigPrintOptionList(cf, pptr->options, 2); + fprintf (cf, " EndSubSection\n"); + } + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } +} + +void +xconfigFreeVendorList (XConfigVendorPtr *p) +{ + if (p == NULL || *p == NULL) + return; + + xconfigFreeVendorSubList (&((*p)->subs)); + TEST_FREE ((*p)->identifier); + TEST_FREE ((*p)->comment); + xconfigFreeOptionList (&((*p)->options)); + free (*p); + *p = NULL; +} + +void +xconfigFreeVendorSubList (XConfigVendSubPtr *ptr) +{ + XConfigVendSubPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->name); + TEST_FREE ((*ptr)->comment); + xconfigFreeOptionList (&((*ptr)->options)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +XConfigVendorPtr +xconfigFindVendor (const char *name, XConfigVendorPtr list) +{ + while (list) + { + if (xconfigNameCompare (list->identifier, name) == 0) + return (list); + list = list->next; + } + return (NULL); +} + diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Video.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Video.c new file mode 100644 index 0000000..2a66dce --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Video.c @@ -0,0 +1,290 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +extern LexRec val; + +static XConfigSymTabRec VideoPortTab[] = +{ + {ENDSUBSECTION, "endsubsection"}, + {IDENTIFIER, "identifier"}, + {OPTION, "option"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeVideoPortList + +XConfigVideoPortPtr +xconfigParseVideoPortSubSection (void) +{ + int has_ident = FALSE; + int token; + PARSE_PROLOGUE (XConfigVideoPortPtr, XConfigVideoPortRec) + + while ((token = xconfigGetToken (VideoPortTab)) != ENDSUBSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + ptr->identifier = val.str; + has_ident = TRUE; + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + return ptr; +} + +#undef CLEANUP + +static XConfigSymTabRec VideoAdaptorTab[] = +{ + {ENDSECTION, "endsection"}, + {IDENTIFIER, "identifier"}, + {VENDOR, "vendorname"}, + {BOARD, "boardname"}, + {BUSID, "busid"}, + {DRIVER, "driver"}, + {OPTION, "option"}, + {SUBSECTION, "subsection"}, + {-1, ""}, +}; + +#define CLEANUP xconfigFreeVideoAdaptorList + +XConfigVideoAdaptorPtr +xconfigParseVideoAdaptorSection (void) +{ + int has_ident = FALSE; + int token; + + PARSE_PROLOGUE (XConfigVideoAdaptorPtr, XConfigVideoAdaptorRec) + + while ((token = xconfigGetToken (VideoAdaptorTab)) != ENDSECTION) + { + switch (token) + { + case COMMENT: + ptr->comment = xconfigAddComment(ptr->comment, val.str); + break; + case IDENTIFIER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Identifier"); + ptr->identifier = val.str; + if (has_ident == TRUE) + Error (MULTIPLE_MSG, "Identifier"); + has_ident = TRUE; + break; + case VENDOR: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Vendor"); + ptr->vendor = val.str; + break; + case BOARD: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Board"); + ptr->board = val.str; + break; + case BUSID: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "BusID"); + ptr->busid = val.str; + break; + case DRIVER: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "Driver"); + ptr->driver = val.str; + break; + case OPTION: + ptr->options = xconfigParseOption(ptr->options); + break; + case SUBSECTION: + if (xconfigGetSubToken (&(ptr->comment)) != STRING) + Error (QUOTE_MSG, "SubSection"); + { + HANDLE_LIST (ports, xconfigParseVideoPortSubSection, + XConfigVideoPortPtr); + } + break; + + case EOF_TOKEN: + Error (UNEXPECTED_EOF_MSG, NULL); + break; + default: + Error (INVALID_KEYWORD_MSG, xconfigTokenString ()); + break; + } + } + + if (!has_ident) + Error (NO_IDENT_MSG, NULL); + + return ptr; +} + +void +xconfigPrintVideoAdaptorSection (FILE * cf, XConfigVideoAdaptorPtr ptr) +{ + XConfigVideoPortPtr pptr; + + while (ptr) + { + fprintf (cf, "Section \"VideoAdaptor\"\n"); + if (ptr->comment) + fprintf (cf, "%s", ptr->comment); + if (ptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", ptr->identifier); + if (ptr->vendor) + fprintf (cf, " VendorName \"%s\"\n", ptr->vendor); + if (ptr->board) + fprintf (cf, " BoardName \"%s\"\n", ptr->board); + if (ptr->busid) + fprintf (cf, " BusID \"%s\"\n", ptr->busid); + if (ptr->driver) + fprintf (cf, " Driver \"%s\"\n", ptr->driver); + xconfigPrintOptionList(cf, ptr->options, 1); + for (pptr = ptr->ports; pptr; pptr = pptr->next) + { + fprintf (cf, " SubSection \"VideoPort\"\n"); + if (pptr->comment) + fprintf (cf, "%s", pptr->comment); + if (pptr->identifier) + fprintf (cf, " Identifier \"%s\"\n", pptr->identifier); + xconfigPrintOptionList(cf, pptr->options, 2); + fprintf (cf, " EndSubSection\n"); + } + fprintf (cf, "EndSection\n\n"); + ptr = ptr->next; + } + +} + +void +xconfigFreeVideoAdaptorList (XConfigVideoAdaptorPtr *ptr) +{ + XConfigVideoAdaptorPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->vendor); + TEST_FREE ((*ptr)->board); + TEST_FREE ((*ptr)->busid); + TEST_FREE ((*ptr)->driver); + TEST_FREE ((*ptr)->fwdref); + TEST_FREE ((*ptr)->comment); + xconfigFreeVideoPortList (&((*ptr)->ports)); + xconfigFreeOptionList (&((*ptr)->options)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +void +xconfigFreeVideoPortList (XConfigVideoPortPtr *ptr) +{ + XConfigVideoPortPtr prev; + + if (ptr == NULL || *ptr == NULL) + return; + + while (*ptr) + { + TEST_FREE ((*ptr)->identifier); + TEST_FREE ((*ptr)->comment); + xconfigFreeOptionList (&((*ptr)->options)); + prev = *ptr; + *ptr = (*ptr)->next; + free (prev); + } +} + +XConfigVideoAdaptorPtr +xconfigFindVideoAdaptor (const char *ident, XConfigVideoAdaptorPtr p) +{ + while (p) + { + if (xconfigNameCompare (ident, p->identifier) == 0) + return (p); + + p = p->next; + } + return (NULL); +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/Write.c b/nvidia-xconfig-540.3.0/XF86Config-parser/Write.c new file mode 100644 index 0000000..59f8fe6 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/Write.c @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* View/edit this file with tab stops set to 4 */ + +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" + +#include +#include +#include +#include +#include +#include + + +int xconfigWriteConfigFile (const char *filename, XConfigPtr cptr) +{ + FILE *cf; + char *locale; + + if ((cf = fopen(filename, "w")) == NULL) + { + xconfigErrorMsg(WriteErrorMsg, "Unable to open the file \"%s\" for " + "writing (%s).\n", filename, strerror(errno)); + return FALSE; + } + + /* + * read the current locale and then set the standard "C" locale, + * so that the X configuration writer does not use locale-specific + * formatting. After writing the configuration file, we restore + * the original locale. + */ + + locale = setlocale(LC_ALL, NULL); + + if (locale) locale = strdup(locale); + + setlocale(LC_ALL, "C"); + + + if (cptr->comment) + fprintf (cf, "%s\n", cptr->comment); + + xconfigPrintLayoutSection (cf, cptr->layouts); + + if (cptr->files) { + fprintf (cf, "Section \"Files\"\n"); + xconfigPrintFileSection (cf, cptr->files); + fprintf (cf, "EndSection\n\n"); + } + + if (cptr->modules) { + fprintf (cf, "Section \"Module\"\n"); + xconfigPrintModuleSection (cf, cptr->modules); + fprintf (cf, "EndSection\n\n"); + } + + xconfigPrintVendorSection (cf, cptr->vendors); + + xconfigPrintServerFlagsSection (cf, cptr->flags); + + xconfigPrintInputSection (cf, cptr->inputs); + + xconfigPrintInputClassSection (cf, cptr->inputclasses); + + xconfigPrintVideoAdaptorSection (cf, cptr->videoadaptors); + + xconfigPrintModesSection (cf, cptr->modes); + + xconfigPrintMonitorSection (cf, cptr->monitors); + + xconfigPrintDeviceSection (cf, cptr->devices); + + xconfigPrintScreenSection (cf, cptr->screens); + + xconfigPrintDRISection (cf, cptr->dri); + + xconfigPrintExtensionsSection (cf, cptr->extensions); + + fclose(cf); + + /* restore the original locale */ + + if (locale) { + setlocale(LC_ALL, locale); + free(locale); + } + + return TRUE; +} diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/configProcs.h b/nvidia-xconfig-540.3.0/XF86Config-parser/configProcs.h new file mode 100644 index 0000000..2f18cb0 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/configProcs.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 1997-2001 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + +/* Private procs. Public procs are in xf86Parser.h and xf86Optrec.h */ + +#include "xf86Parser.h" + + +/* Device.c */ +XConfigDevicePtr xconfigParseDeviceSection(void); +void xconfigPrintDeviceSection(FILE *cf, XConfigDevicePtr ptr); +int xconfigValidateDevice(XConfigPtr p); + +/* Files.c */ +XConfigFilesPtr xconfigParseFilesSection(void); +void xconfigPrintFileSection(FILE *cf, XConfigFilesPtr ptr); + +/* Flags.c */ +XConfigFlagsPtr xconfigParseFlagsSection(void); +void xconfigPrintServerFlagsSection(FILE *f, XConfigFlagsPtr flags); + +/* Input.c */ +XConfigInputPtr xconfigParseInputSection(void); +XConfigInputClassPtr xconfigParseInputClassSection(void); +void xconfigPrintInputSection(FILE *f, XConfigInputPtr ptr); +void xconfigPrintInputClassSection(FILE *f, XConfigInputClassPtr ptr); +int xconfigValidateInput (XConfigPtr p); + +/* Keyboard.c */ +XConfigInputPtr xconfigParseKeyboardSection(void); + +/* Layout.c */ +XConfigLayoutPtr xconfigParseLayoutSection(void); +void xconfigPrintLayoutSection(FILE *cf, XConfigLayoutPtr ptr); +int xconfigValidateLayout(XConfigPtr p); +int xconfigSanitizeLayout(XConfigPtr p, const char *screenName, + GenerateOptions *gop); + +/* Module.c */ +XConfigLoadPtr xconfigParseModuleSubSection(XConfigLoadPtr head, char *name); +XConfigModulePtr xconfigParseModuleSection(void); +void xconfigPrintModuleSection(FILE *cf, XConfigModulePtr ptr); + +/* Monitor.c */ +XConfigModeLinePtr xconfigParseModeLine(void); +XConfigModeLinePtr xconfigParseVerboseMode(void); +XConfigMonitorPtr xconfigParseMonitorSection(void); +XConfigModesPtr xconfigParseModesSection(void); +void xconfigPrintMonitorSection(FILE *cf, XConfigMonitorPtr ptr); +void xconfigPrintModesSection(FILE *cf, XConfigModesPtr ptr); +int xconfigValidateMonitor(XConfigPtr p, XConfigScreenPtr screen); + +/* Pointer.c */ +XConfigInputPtr xconfigParsePointerSection(void); + +/* Screen.c */ +XConfigDisplayPtr xconfigParseDisplaySubSection(void); +XConfigScreenPtr xconfigParseScreenSection(void); +void xconfigPrintScreenSection(FILE *cf, XConfigScreenPtr ptr); +int xconfigValidateScreen(XConfigPtr p); +int xconfigSanitizeScreen(XConfigPtr p); + +/* Vendor.c */ +XConfigVendorPtr xconfigParseVendorSection(void); +XConfigVendSubPtr xconfigParseVendorSubSection (void); +void xconfigPrintVendorSection(FILE * cf, XConfigVendorPtr ptr); + +/* Video.c */ +XConfigVideoPortPtr xconfigParseVideoPortSubSection(void); +XConfigVideoAdaptorPtr xconfigParseVideoAdaptorSection(void); +void xconfigPrintVideoAdaptorSection(FILE *cf, XConfigVideoAdaptorPtr ptr); + +/* Read.c */ +int xconfigValidateConfig(XConfigPtr p); + +/* Scan.c */ +int xconfigGetToken(XConfigSymTabRec *tab); +int xconfigGetSubToken(char **comment); +int xconfigGetSubTokenWithTab(char **comment, XConfigSymTabRec *tab); +void xconfigUnGetToken(int token); +char *xconfigTokenString(void); +void xconfigSetSection(char *section); +int xconfigGetStringToken(XConfigSymTabRec *tab); +char *xconfigGetConfigFileName(void); + +/* Write.c */ + +/* DRI.c */ +XConfigBuffersPtr xconfigParseBuffers (void); +XConfigDRIPtr xconfigParseDRISection (void); +void xconfigPrintDRISection (FILE * cf, XConfigDRIPtr ptr); + +/* Util.c */ +void *xconfigAlloc(size_t size); +void xconfigErrorMsg(MsgType, char *fmt, ...); + +/* Extensions.c */ +XConfigExtensionsPtr xconfigParseExtensionsSection (void); +void xconfigPrintExtensionsSection (FILE * cf, XConfigExtensionsPtr ptr); + +/* Generate.c */ +XConfigMonitorPtr xconfigAddMonitor(XConfigPtr config, int count); +int xconfigAddMouse(GenerateOptions *gop, XConfigPtr config); +int xconfigAddKeyboard(GenerateOptions *gop, XConfigPtr config); diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/src.mk b/nvidia-xconfig-540.3.0/XF86Config-parser/src.mk new file mode 100644 index 0000000..f43afb7 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/src.mk @@ -0,0 +1,29 @@ +# makefile fragment included by nvidia-xconfig and nvidia-settings + +XCONFIG_PARSER_SRC += DRI.c +XCONFIG_PARSER_SRC += Device.c +XCONFIG_PARSER_SRC += Extensions.c +XCONFIG_PARSER_SRC += Files.c +XCONFIG_PARSER_SRC += Flags.c +XCONFIG_PARSER_SRC += Generate.c +XCONFIG_PARSER_SRC += Input.c +XCONFIG_PARSER_SRC += Keyboard.c +XCONFIG_PARSER_SRC += Layout.c +XCONFIG_PARSER_SRC += Merge.c +XCONFIG_PARSER_SRC += Module.c +XCONFIG_PARSER_SRC += Monitor.c +XCONFIG_PARSER_SRC += Pointer.c +XCONFIG_PARSER_SRC += Read.c +XCONFIG_PARSER_SRC += Scan.c +XCONFIG_PARSER_SRC += Screen.c +XCONFIG_PARSER_SRC += Util.c +XCONFIG_PARSER_SRC += Vendor.c +XCONFIG_PARSER_SRC += Video.c +XCONFIG_PARSER_SRC += Write.c + +XCONFIG_PARSER_EXTRA_DIST += Configint.h +XCONFIG_PARSER_EXTRA_DIST += configProcs.h +XCONFIG_PARSER_EXTRA_DIST += xf86Parser.h +XCONFIG_PARSER_EXTRA_DIST += xf86tokens.h +XCONFIG_PARSER_EXTRA_DIST += src.mk + diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/xf86Parser.h b/nvidia-xconfig-540.3.0/XF86Config-parser/xf86Parser.h new file mode 100644 index 0000000..92144a4 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/xf86Parser.h @@ -0,0 +1,800 @@ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +/* + * This file specifies the external interface for the X configuration + * file parser; based loosely on the XFree86 and Xorg X server + * configuration code. + */ + + +#ifndef _xf86Parser_h_ +#define _xf86Parser_h_ + +#include + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +// Unix variations: Linux +#if !defined(NV_LINUX) && defined(__linux__) +# define NV_LINUX +#endif // defined(__linux__) + +// Unix variations: SunOS +#if !defined(NV_SUNOS) && (defined(__sun__) || defined(__sun)) +# define NV_SUNOS +#endif // defined(__sun__) + +// Unix variations: FreeBSD +#if !defined(NV_BSD) && defined(__FreeBSD__) +# define NV_BSD +#endif // defined(__FreeBSD__) + + +/* + * return codes + */ + +typedef enum { + XCONFIG_RETURN_SUCCESS = 0, + XCONFIG_RETURN_NO_XCONFIG_FOUND, + XCONFIG_RETURN_PARSE_ERROR, + XCONFIG_RETURN_ALLOCATION_ERROR, + XCONFIG_RETURN_VALIDATION_ERROR, + XCONFIG_RETURN_INVALID_COMMAND_LINE, + XCONFIG_RETURN_SANITY_ERROR, + XCONFIG_RETURN_WRITE_ERROR +} XConfigError; + + +/* + * Message types + */ + +typedef enum { + ParseErrorMsg, + ParseWarningMsg, + ValidationErrorMsg, + InternalErrorMsg, + WriteErrorMsg, + WarnMsg, + ErrorMsg, + DebugMsg, + UnknownMsg +} MsgType; + + +/* + * The user of libXF86Config-parser should provide an implementation + * of xconfigPrint() + */ + +void xconfigPrint(MsgType t, const char *msg); + + +/* + * all records that need to be linked lists should contain a next + * pointer as their first field, so that they can be cast as a + * GenericListRec + */ + +typedef struct { void *next; } GenericListRec, *GenericListPtr; + + + +/* + * Options are stored in the XConfigOptionRec structure + */ + +typedef struct __xconfigoptionrec { + struct __xconfigoptionrec *next; + char *name; + char *val; + char *comment; +} XConfigOptionRec, *XConfigOptionPtr; + + + +/* + * Files Section + */ + +typedef struct { + char *logfile; + char *rgbpath; + char *modulepath; + char *inputdevs; + char *fontpath; + char *comment; +} XConfigFilesRec, *XConfigFilesPtr; + +/* Values for load_type */ +#define XCONFIG_LOAD_MODULE 0 +#define XCONFIG_LOAD_DRIVER 1 +#define XCONFIG_DISABLE_MODULE 2 + + +/* + * Modules Section + */ + +typedef struct __xconfigloadrec { + struct __xconfigloadrec *next; + int type; + char *name; + XConfigOptionPtr opt; + char *comment; +} XConfigLoadRec, *XConfigLoadPtr; + +typedef struct { + XConfigLoadPtr loads; + XConfigLoadPtr disables; + char *comment; +} XConfigModuleRec, *XConfigModulePtr; + +#define CONF_IMPLICIT_KEYBOARD "Implicit Core Keyboard" + +#define CONF_IMPLICIT_POINTER "Implicit Core Pointer" + + + +/* + * Modeline structure + */ + +#define XCONFIG_MODE_PHSYNC 0x0001 +#define XCONFIG_MODE_NHSYNC 0x0002 +#define XCONFIG_MODE_PVSYNC 0x0004 +#define XCONFIG_MODE_NVSYNC 0x0008 +#define XCONFIG_MODE_INTERLACE 0x0010 +#define XCONFIG_MODE_DBLSCAN 0x0020 +#define XCONFIG_MODE_CSYNC 0x0040 +#define XCONFIG_MODE_PCSYNC 0x0080 +#define XCONFIG_MODE_NCSYNC 0x0100 +#define XCONFIG_MODE_HSKEW 0x0200 /* hskew provided */ +#define XCONFIG_MODE_BCAST 0x0400 +#define XCONFIG_MODE_CUSTOM 0x0800 /* timing numbers customized by editor */ +#define XCONFIG_MODE_VSCAN 0x1000 + +typedef struct __xconfigconfmodelinerec { + struct __xconfigconfmodelinerec *next; + char *identifier; + char *clock; /* stored in MHz */ + int hdisplay; + int hsyncstart; + int hsyncend; + int htotal; + int vdisplay; + int vsyncstart; + int vsyncend; + int vtotal; + int vscan; + int flags; + int hskew; + char *comment; +} XConfigModeLineRec, *XConfigModeLinePtr; + + + +/* + * VideoPort and VideoAdapter XXX what are these? + */ + +typedef struct __xconfigconfvideoportrec { + struct __xconfigconfvideoportrec *next; + char *identifier; + XConfigOptionPtr options; + char *comment; +} XConfigVideoPortRec, *XConfigVideoPortPtr; + +typedef struct __xconfigconfvideoadaptorrec { + struct __xconfigconfvideoadaptorrec *next; + char *identifier; + char *vendor; + char *board; + char *busid; + char *driver; + XConfigOptionPtr options; + XConfigVideoPortPtr ports; + char *fwdref; + char *comment; +} XConfigVideoAdaptorRec, *XConfigVideoAdaptorPtr; + + + +/* + * Monitor Section + */ + +#define CONF_MAX_HSYNC 8 +#define CONF_MAX_VREFRESH 8 + +typedef struct { float hi, lo; } parser_range; + +typedef struct { int red, green, blue; } parser_rgb; + +typedef struct __xconfigconfmodesrec { + struct __xconfigconfmodesrec *next; + char *identifier; + XConfigModeLinePtr modelines; + char *comment; +} XConfigModesRec, *XConfigModesPtr; + +typedef struct __xconfigconfmodeslinkrec { + struct __xconfigconfmodeslinkrec *next; + char *modes_name; + XConfigModesPtr modes; +} XConfigModesLinkRec, *XConfigModesLinkPtr; + +typedef struct __xconfigconfmonitorrec { + struct __xconfigconfmonitorrec *next; + char *identifier; + char *vendor; + char *modelname; + int width; /* in mm */ + int height; /* in mm */ + XConfigModeLinePtr modelines; + int n_hsync; + parser_range hsync[CONF_MAX_HSYNC]; + int n_vrefresh; + parser_range vrefresh[CONF_MAX_VREFRESH]; + float gamma_red; + float gamma_green; + float gamma_blue; + XConfigOptionPtr options; + XConfigModesLinkPtr modes_sections; + char *comment; +} XConfigMonitorRec, *XConfigMonitorPtr; + + + +/* + * Device Section + */ + +#define CONF_MAXDACSPEEDS 4 +#define CONF_MAXCLOCKS 128 + +typedef struct __xconfigconfdevicerec { + struct __xconfigconfdevicerec *next; + char *identifier; + char *vendor; + char *board; + char *chipset; + char *busid; + char *card; + char *driver; + char *ramdac; + int dacSpeeds[CONF_MAXDACSPEEDS]; + int videoram; + int textclockfreq; + unsigned long bios_base; + unsigned long mem_base; + unsigned long io_base; + char *clockchip; + int clocks; + int clock[CONF_MAXCLOCKS]; + int chipid; + int chiprev; + int irq; + int screen; + size_t index_id; + XConfigOptionPtr options; + char *comment; +} XConfigDeviceRec, *XConfigDevicePtr; + + + +/* + * Screen Section + */ + +typedef struct __xconfigmoderec { + struct __xconfigmoderec *next; + char *mode_name; +} XConfigModeRec, *XConfigModePtr; + +typedef struct __xconfigconfdisplayrec { + struct __xconfigconfdisplayrec *next; + int frameX0; + int frameY0; + int virtualX; + int virtualY; + int depth; + int bpp; + char *visual; + parser_rgb weight; + parser_rgb black; + parser_rgb white; + XConfigModePtr modes; + XConfigOptionPtr options; + char *comment; +} XConfigDisplayRec, *XConfigDisplayPtr; + +typedef struct __xconfigconfadaptorlinkrec { + struct __xconfigconfadaptorlinkrec *next; + char *adaptor_name; + XConfigVideoAdaptorPtr adaptor; +} XConfigAdaptorLinkRec, *XConfigAdaptorLinkPtr; + +typedef struct __xconfigconfscreenrec { + struct __xconfigconfscreenrec *next; + char *identifier; + char *obsolete_driver; + int defaultdepth; + int defaultbpp; + int defaultfbbpp; + char *monitor_name; + XConfigMonitorPtr monitor; + char *device_name; + XConfigDevicePtr device; + XConfigAdaptorLinkPtr adaptors; + XConfigDisplayPtr displays; + XConfigOptionPtr options; + char *comment; +} XConfigScreenRec, *XConfigScreenPtr; + + + +/* + * Input Section + */ + +typedef struct __xconfigconfinputrec { + struct __xconfigconfinputrec *next; + char *identifier; + char *driver; + XConfigOptionPtr options; + char *comment; +} XConfigInputRec, *XConfigInputPtr; + + + +/* + * Input Class Section + */ + +typedef struct __xconfigconfinputclassrec { + struct __xconfigconfinputclassrec *next; + char *identifier; + char *driver; + char *match_is_pointer; + char *match_is_touchpad; + char *match_is_touchscreen; + char *match_is_keyboard; + char *match_is_joystick; + char *match_is_tablet; + char *match_tag; + char *match_device_path; + char *match_os; + char *match_usb_id; + char *match_pnp_id; + char *match_product; + char *match_driver; + char *match_vendor; + XConfigOptionPtr options; + char *comment; +} XConfigInputClassRec, *XConfigInputClassPtr; + + + +/* + * Input Reference; used by layout to store list of XConfigInputPtrs + */ + +typedef struct __xconfigconfinputrefrec { + struct __xconfigconfinputrefrec *next; + XConfigInputPtr input; + char *input_name; + XConfigOptionPtr options; +} XConfigInputrefRec, *XConfigInputrefPtr; + + + +/* + * Adjacency structure; used by layout to store list of + * XConfigScreenPtrs + */ + +/* Values for adj_where */ +#define CONF_ADJ_OBSOLETE -1 +#define CONF_ADJ_ABSOLUTE 0 +#define CONF_ADJ_RIGHTOF 1 +#define CONF_ADJ_LEFTOF 2 +#define CONF_ADJ_ABOVE 3 +#define CONF_ADJ_BELOW 4 +#define CONF_ADJ_RELATIVE 5 + +typedef struct __xconfigconfadjacencyrec { + struct __xconfigconfadjacencyrec *next; + int scrnum; + XConfigScreenPtr screen; + char *screen_name; + XConfigScreenPtr top; + char *top_name; + XConfigScreenPtr bottom; + char *bottom_name; + XConfigScreenPtr left; + char *left_name; + XConfigScreenPtr right; + char *right_name; + int where; + int x; + int y; + char *refscreen; +} XConfigAdjacencyRec, *XConfigAdjacencyPtr; + + + +/* + * XConfigInactiveRec XXX what is this? + */ + +typedef struct __xconfigconfinactiverec { + struct __xconfigconfinactiverec *next; + char *device_name; + XConfigDevicePtr device; +} XConfigInactiveRec, *XConfigInactivePtr; + + + +/* + * Layout Section + */ + +typedef struct __xconfigconflayoutrec { + struct __xconfigconflayoutrec *next; + char *identifier; + XConfigAdjacencyPtr adjacencies; + XConfigInactivePtr inactives; + XConfigInputrefPtr inputs; + XConfigOptionPtr options; + char *comment; +} XConfigLayoutRec, *XConfigLayoutPtr; + + + +/* + * Vendor Section XXX what is this? + */ + +typedef struct __xconfigconfvendsubrec { + struct __xconfigconfvendsubrec *next; + char *name; + char *identifier; + XConfigOptionPtr options; + char *comment; +} XConfigVendSubRec, *XConfigVendSubPtr; + +typedef struct __xconfigconfvendorrec { + struct __xconfigconfvendorrec *next; + char *identifier; + XConfigOptionPtr options; + XConfigVendSubPtr subs; + char *comment; +} XConfigVendorRec, *XConfigVendorPtr; + + + +/* + * DRI section + */ + +typedef struct __xconfigconfbuffersrec { + struct __xconfigconfbuffersrec *next; + int count; + int size; + char *flags; + char *comment; +} XConfigBuffersRec, *XConfigBuffersPtr; + +typedef struct { + char *group_name; + int group; + int mode; + XConfigBuffersPtr buffers; + char * comment; +} XConfigDRIRec, *XConfigDRIPtr; + + + +/* + * ServerFlags Section + */ + +typedef struct { + XConfigOptionPtr options; + char *comment; +} XConfigFlagsRec, *XConfigFlagsPtr; + + + +/* + * Extensions Section + */ + +typedef struct +{ + XConfigOptionPtr options; + char *comment; +} +XConfigExtensionsRec, *XConfigExtensionsPtr; + + +/* + * Configuration file structure + */ + +typedef struct { + XConfigFilesPtr files; + XConfigModulePtr modules; + XConfigFlagsPtr flags; + XConfigVideoAdaptorPtr videoadaptors; + XConfigModesPtr modes; + XConfigMonitorPtr monitors; + XConfigDevicePtr devices; + XConfigScreenPtr screens; + XConfigInputPtr inputs; + XConfigInputClassPtr inputclasses; + XConfigLayoutPtr layouts; + XConfigVendorPtr vendors; + XConfigDRIPtr dri; + XConfigExtensionsPtr extensions; + char *comment; + char *filename; +} XConfigRec, *XConfigPtr; + +typedef struct { + int token; /* id of the token */ + char *name; /* pointer to the LOWERCASED name */ +} XConfigSymTabRec, *XConfigSymTabPtr; + + +/* + * data structure containing options; used during generation of X + * config, and when sanitizing an existing config + */ + +typedef struct { + char *x_project_root; + char *keyboard; + char *mouse; + char *keyboard_driver; + + int supports_extension_section; + int autoloads_glx; + int xinerama_plus_composite_works; + const char *compositeExtensionName; + +} GenerateOptions; + + +/* + * Functions for open, reading, and writing XConfig files. + */ +const char *xconfigOpenConfigFile(const char *, const char *); +XConfigError xconfigReadConfigFile(XConfigPtr *); +int xconfigSanitizeConfig(XConfigPtr p, const char *screenName, + GenerateOptions *gop); +void xconfigCloseConfigFile(void); +int xconfigWriteConfigFile(const char *, XConfigPtr); + +void xconfigFreeConfig(XConfigPtr *p); + +/* + * Functions for searching for entries in lists + */ + +XConfigDevicePtr xconfigFindDevice(const char *ident, XConfigDevicePtr p); +XConfigLayoutPtr xconfigFindLayout(const char *name, XConfigLayoutPtr list); +XConfigMonitorPtr xconfigFindMonitor(const char *ident, XConfigMonitorPtr p); +XConfigModesPtr xconfigFindModes(const char *ident, XConfigModesPtr p); +XConfigModeLinePtr xconfigFindModeLine(const char *ident, + XConfigModeLinePtr p); +XConfigScreenPtr xconfigFindScreen(const char *ident, XConfigScreenPtr p); +XConfigModePtr xconfigFindMode(const char *name, XConfigModePtr p); +XConfigInputPtr xconfigFindInput(const char *ident, XConfigInputPtr p); +XConfigInputPtr xconfigFindInputByDriver(const char *driver, + XConfigInputPtr p); +XConfigVendorPtr xconfigFindVendor(const char *name, XConfigVendorPtr list); +XConfigVideoAdaptorPtr xconfigFindVideoAdaptor(const char *ident, + XConfigVideoAdaptorPtr p); + +/* + * Functions for freeing lists + */ + +void xconfigFreeDeviceList(XConfigDevicePtr *ptr); +void xconfigFreeFiles(XConfigFilesPtr *p); +void xconfigFreeFlags(XConfigFlagsPtr *flags); +void xconfigFreeInputList(XConfigInputPtr *ptr); +void xconfigFreeInputClassList(XConfigInputClassPtr *ptr); +void xconfigFreeLayoutList(XConfigLayoutPtr *ptr); +void xconfigFreeAdjacencyList(XConfigAdjacencyPtr *ptr); +void xconfigFreeInputrefList(XConfigInputrefPtr *ptr); +void xconfigFreeModules(XConfigModulePtr *ptr); +void xconfigFreeMonitorList(XConfigMonitorPtr *ptr); +void xconfigFreeModesList(XConfigModesPtr *ptr); +void xconfigFreeModeLineList(XConfigModeLinePtr *ptr); +void xconfigFreeOptionList(XConfigOptionPtr *opt); +void xconfigFreeScreenList(XConfigScreenPtr *ptr); +void xconfigFreeAdaptorLinkList(XConfigAdaptorLinkPtr *ptr); +void xconfigFreeDisplayList(XConfigDisplayPtr *ptr); +void xconfigFreeModeList(XConfigModePtr *ptr); +void xconfigFreeVendorList(XConfigVendorPtr *p); +void xconfigFreeVendorSubList(XConfigVendSubPtr *ptr); +void xconfigFreeVideoAdaptorList(XConfigVideoAdaptorPtr *ptr); +void xconfigFreeVideoPortList(XConfigVideoPortPtr *ptr); +void xconfigFreeBuffersList (XConfigBuffersPtr *ptr); +void xconfigFreeDRI(XConfigDRIPtr *ptr); +void xconfigFreeExtensions(XConfigExtensionsPtr *ptr); +void xconfigFreeModesLinkList(XConfigModesLinkPtr *ptr); + + + +/* + * item/list manipulation + */ + +void xconfigAddListItem(GenericListPtr *pHead, GenericListPtr c_new); +void xconfigRemoveListItem(GenericListPtr *pHead, GenericListPtr item); +int xconfigItemNotSublist(GenericListPtr list_1, GenericListPtr list_2); +char *xconfigAddComment(char *cur, char *add); +void xconfigAddNewLoadDirective(XConfigLoadPtr *pHead, + char *name, int type, + XConfigOptionPtr opts, int do_token); +void xconfigRemoveLoadDirective(XConfigLoadPtr *pHead, XConfigLoadPtr load); + +/* + * Functions for manipulating Options + */ + +void xconfigAddNewOption(XConfigOptionPtr *pHead, + const char *name, const char *val); +void xconfigRemoveOption(XConfigOptionPtr *pHead, XConfigOptionPtr opt); +void xconfigRemoveNamedOption(XConfigOptionPtr *head, const char *name, + char **comments); + +XConfigOptionPtr xconfigOptionListDup(XConfigOptionPtr opt); +char *xconfigOptionName(XConfigOptionPtr opt); +char *xconfigOptionValue(XConfigOptionPtr opt); +XConfigOptionPtr xconfigNewOption(const char *name, const char *value); +XConfigOptionPtr xconfigNextOption(XConfigOptionPtr list); +XConfigOptionPtr xconfigFindOption(XConfigOptionPtr list, const char *name); +char *xconfigFindOptionValue(XConfigOptionPtr list, + const char *name); +int xconfigFindOptionBoolean (XConfigOptionPtr, + const char *name); +XConfigOptionPtr xconfigOptionListMerge(XConfigOptionPtr head, + XConfigOptionPtr tail); + +/* + * Miscellaneous utility routines + */ + +char *xconfigStrdup(const char *s); +char *xconfigStrcat(const char *str, ...); +int xconfigNameCompare(const char *s1, const char *s2); +int xconfigModelineCompare(XConfigModeLinePtr m1, XConfigModeLinePtr m2); +char *xconfigULongToString(unsigned long i); +XConfigOptionPtr xconfigParseOption(XConfigOptionPtr head); +void xconfigPrintOptionList(FILE *fp, XConfigOptionPtr list, int tabs); +int xconfigParsePciBusString(const char *busID, + int *bus, int *device, int *func); +void xconfigFormatPciBusString(char *str, int len, + int domain, int bus, int device, int func); + +void xconfigAddDisplay(XConfigDisplayPtr *pHead, const int depth); + +void xconfigAddMode(XConfigModePtr *pHead, const char *name); +void xconfigRemoveMode(XConfigModePtr *pHead, const char *name); + +XConfigPtr xconfigGenerate(GenerateOptions *gop); + +XConfigScreenPtr xconfigGenerateAddScreen(XConfigPtr config, + int bus, int domain, int slot, + char *boardname, int count, + const char *driver, + const char *vendor); + +XConfigDevicePtr add_device(XConfigPtr config, int bus, int domain, + int slot, char *boardname, int count, + const char *driver, const char *vendor, int active); + +void xconfigAddInactiveDevice(XConfigPtr config, XConfigLayoutPtr layout, + int device_n); + +void xconfigGenerateAssignScreenAdjacencies(XConfigLayoutPtr layout); + +void xconfigGeneratePrintPossibleMice(void); +void xconfigGeneratePrintPossibleKeyboards(void); +void xconfigGenerateLoadDefaultOptions(GenerateOptions *gop); + +void xconfigGetXServerInUse(GenerateOptions *gop); + +char *xconfigValidateComposite(XConfigPtr config, + GenerateOptions *gop, + int composite_enabled, + int xinerama_enabled, + int depth, + int overlay_enabled, + int cioverlay_enabled, + int ubb_enabled, + int stereo); + +/* + * check (and update, if necessary) the inputs in the specified layout + * section + */ + +int xconfigCheckCoreInputDevices(GenerateOptions *gop, + XConfigPtr config, XConfigLayoutPtr layout); + + +/* + * X config tools + */ + +int xconfigMergeConfigs(XConfigPtr dstConfig, XConfigPtr srcConfig); + + + +#endif /* _xf86Parser_h_ */ diff --git a/nvidia-xconfig-540.3.0/XF86Config-parser/xf86tokens.h b/nvidia-xconfig-540.3.0/XF86Config-parser/xf86tokens.h new file mode 100644 index 0000000..67c1df0 --- /dev/null +++ b/nvidia-xconfig-540.3.0/XF86Config-parser/xf86tokens.h @@ -0,0 +1,293 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/parser/xf86tokens.h,v 1.20 2003/08/24 17:37:09 dawes Exp $ */ +/* + * + * Copyright (c) 1997 Metro Link Incorporated + * + * 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 X CONSORTIUM 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. + * + * Except as contained in this notice, the name of the Metro Link shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Metro Link. + * + */ +/* + * Copyright (c) 1997-2003 by The XFree86 Project, Inc. + * + * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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. + * + * Except as contained in this notice, the name of the copyright holder(s) + * and author(s) shall not be used in advertising or otherwise to promote + * the sale, use or other dealings in this Software without prior written + * authorization from the copyright holder(s) and author(s). + */ + + +#ifndef _xf86_tokens_h +#define _xf86_tokens_h + +/* Undefine symbols that some OSs might define */ +#undef IOBASE + +/* + * Each token should have a unique value regardless of the section + * it is used in. + */ + +typedef enum { + /* errno-style tokens */ + EOF_TOKEN = -4, + LOCK_TOKEN = -3, + ERROR_TOKEN = -2, + + /* value type tokens */ + NUMBER = 1, + STRING, + + /* Tokens that can appear in many sections */ + SECTION, + SUBSECTION, + ENDSECTION, + ENDSUBSECTION, + IDENTIFIER, + VENDOR, + DASH, + COMMA, + OPTION, + COMMENT, + + /* Frequency units */ + HRZ, + KHZ, + MHZ, + + /* File tokens */ + FONTPATH, + RGBPATH, + MODULEPATH, + INPUTDEVICES, + LOGFILEPATH, + + /* Server Flag tokens. These are deprecated in favour of generic Options */ + NOTRAPSIGNALS, + DONTZAP, + DONTZOOM, + DISABLEVIDMODE, + ALLOWNONLOCAL, + DISABLEMODINDEV, + MODINDEVALLOWNONLOCAL, + ALLOWMOUSEOPENFAIL, + BLANKTIME, + STANDBYTIME, + SUSPENDTIME, + OFFTIME, + DEFAULTLAYOUT, + + /* Monitor tokens */ + MODEL, + MODELINE, + DISPLAYSIZE, + HORIZSYNC, + VERTREFRESH, + MODE, + GAMMA, + USEMODES, + + /* Modes tokens */ + /* no new ones */ + + /* Mode tokens */ + DOTCLOCK, + HTIMINGS, + VTIMINGS, + FLAGS, + HSKEW, + BCAST, + VSCAN, + ENDMODE, + + /* Screen tokens */ + OBSDRIVER, + MDEVICE, + MONITOR, + SCREENNO, + DEFAULTDEPTH, + DEFAULTBPP, + DEFAULTFBBPP, + + /* VideoAdaptor tokens */ + VIDEOADAPTOR, + + /* Mode timing tokens */ + TT_INTERLACE, + TT_PHSYNC, + TT_NHSYNC, + TT_PVSYNC, + TT_NVSYNC, + TT_CSYNC, + TT_PCSYNC, + TT_NCSYNC, + TT_DBLSCAN, + TT_HSKEW, + TT_BCAST, + TT_VSCAN, + TT_CUSTOM, + + /* Module tokens */ + LOAD, + LOAD_DRIVER, + DISABLE, + + /* InputClass tokens */ + MATCHPRODUCT, + MATCHISPOINTER, + MATCHISTOUCHPAD, + MATCHISTOUCHSCREEN, + MATCHISKEYBOARD, + MATCHISJOYSTICK, + MATCHISTABLET, + MATCHOS, + MATCHTAG, + MATCHUSBID, + MATCHPNPID, + MATCHVENDOR, + MATCHDRIVER, + MATCHDEVICEPATH, + + /* Device tokens */ + DRIVER, + CHIPSET, + CLOCKS, + VIDEORAM, + BOARD, + IOBASE, + RAMDAC, + DACSPEED, + BIOSBASE, + MEMBASE, + CLOCKCHIP, + CHIPID, + CHIPREV, + CARD, + BUSID, + TEXTCLOCKFRQ, + IRQ, + + /* Keyboard tokens */ + AUTOREPEAT, + XLEDS, + KPROTOCOL, + XKBKEYMAP, + XKBCOMPAT, + XKBTYPES, + XKBKEYCODES, + XKBGEOMETRY, + XKBSYMBOLS, + XKBDISABLE, + PANIX106, + XKBRULES, + XKBMODEL, + XKBLAYOUT, + XKBVARIANT, + XKBOPTIONS, + /* The next two have become ServerFlags options */ + VTINIT, + VTSYSREQ, + /* Obsolete keyboard tokens */ + SERVERNUM, + LEFTALT, + RIGHTALT, + SCROLLLOCK_TOK, + RIGHTCTL, + /* arguments for the above obsolete tokens */ + CONF_KM_META, + CONF_KM_COMPOSE, + CONF_KM_MODESHIFT, + CONF_KM_MODELOCK, + CONF_KM_SCROLLLOCK, + CONF_KM_CONTROL, + + /* Pointer tokens */ + EMULATE3, + BAUDRATE, + SAMPLERATE, + PRESOLUTION, + CLEARDTR, + CLEARRTS, + CHORDMIDDLE, + PROTOCOL, + PDEVICE, + EM3TIMEOUT, + DEVICE_NAME, + ALWAYSCORE, + PBUTTONS, + ZAXISMAPPING, + + /* Pointer Z axis mapping tokens */ + XAXIS, + YAXIS, + + /* Display tokens */ + MODES, + VIEWPORT, + VIRTUAL, + VISUAL, + BLACK_TOK, + WHITE_TOK, + DEPTH, + BPP, + WEIGHT, + + /* Layout Tokens */ + SCREEN, + INACTIVE, + INPUTDEVICE, + + /* Adjaceny Tokens */ + RIGHTOF, + LEFTOF, + ABOVE, + BELOW, + RELATIVE, + ABSOLUTE, + + /* Vendor Tokens */ + VENDORNAME, + + /* DRI Tokens */ + GROUP, + BUFFERS +} ParserTokens; + +#endif /* _xf86_tokens_h */ diff --git a/nvidia-xconfig-540.3.0/common-utils/common-utils.c b/nvidia-xconfig-540.3.0/common-utils/common-utils.c new file mode 100644 index 0000000..c549e97 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/common-utils.c @@ -0,0 +1,826 @@ +/* + * Copyright (C) 2010-2012 NVIDIA Corporation + * + * 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. + */ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "common-utils.h" + + +/****************************************************************************/ +/* Memory allocation helper functions */ +/****************************************************************************/ + +/* + * nvalloc() - calloc wrapper that checks for errors; if an error + * occurs, an error is printed to stderr and exit is called -- this + * function will only return on success. + */ + +void *nvalloc(size_t size) +{ + void *m = calloc(1, size); + + if (!m) { + fprintf(stderr, "%s: memory allocation failure (%s)! \n", + PROGRAM_NAME, strerror(errno)); + exit(1); + } + return m; + +} /* nvalloc() */ + + + +/* + * nvstrcat() - allocate a new string, copying all given strings + * into it. + */ + +char *nvstrcat(const char *str, ...) +{ + const char *s; + char *result; + size_t len; + va_list ap; + + /* walk the varargs to compute the length of the result string */ + + va_start(ap, str); + + for (s = str, len = 1; s; s = va_arg(ap, char *)) { + len += strlen(s); + } + + va_end(ap); + + /* allocate the result string */ + + result = nvalloc(len); + if (!result) { + return result; + } + result[0] = '\0'; + + /* concatenate the input strings, writing into the result string */ + + va_start(ap, str); + + for (s = str; s; s = va_arg(ap, char *)) { + strcat(result, s); + } + + va_end(ap); + + return result; +} /* nvstrcat() */ + + + +/* + * nvrealloc() - realloc wrapper that checks for errors; if an error + * occurs, an error is printed to stderr and exit is called -- this + * function will only return on success. + */ + +void *nvrealloc(void *ptr, size_t size) +{ + void *m; + + if (ptr == NULL) return nvalloc(size); + + m = realloc(ptr, size); + if (!m) { + fprintf(stderr, "%s: memory re-allocation failure (%s)! \n", + PROGRAM_NAME, strerror(errno)); + exit(1); + } + return m; + +} /* nvrealloc() */ + + + +/* + * nvstrdup() - wrapper for strdup() that checks the return value; if + * an error occurs, an error is printed to stderr and exit is called + * -- this function will only return on success. + */ + +char *nvstrdup(const char *s) +{ + char *m; + + if (!s) return NULL; + + m = strdup(s); + + if (!m) { + fprintf(stderr, "%s: memory allocation failure during strdup (%s)! \n", + PROGRAM_NAME, strerror(errno)); + exit(1); + } + return m; + +} /* nvstrdup() */ + + + +/* + * nvstrndup() - implementation of strndup() that checks return values; if + * an error occurs, an error is printed to stderr and exit is called + * -- this function will only return on success. + */ + +char *nvstrndup(const char *s, size_t n) +{ + char *m; + + if (!s) return NULL; + + m = malloc(n + 1); + + if (!m) { + fprintf(stderr, "%s: memory allocation failure during malloc (%s)! \n", + PROGRAM_NAME, strerror(errno)); + exit(1); + } + + strncpy (m, s, n); + m[n] = '\0'; + + return m; + +} /* nvstrndup() */ + + + +/* + * nvstrtolower() - convert the given string to lowercase. + */ + +char *nvstrtolower(char *s) +{ + char *start = s; + + if (s == NULL) return NULL; + + while (*s) { + *s = tolower(*s); + s++; + } + + return start; + +} /* nvstrtolower() */ + + + +/* + * nvstrtoupper() - convert the given string to uppercase. + */ + +char *nvstrtoupper(char *s) +{ + char *start = s; + + if (s == NULL) return NULL; + + while (*s) { + *s = toupper(*s); + s++; + } + + return start; + +} /* nvstrtoupper() */ + + + +/* + * nvasprintf() - implementation of asprintf() that checks return values; if an + * error occurs, an error is printed to stderr and exit is called. + * -- this function will only return on success. + */ +char *nvasprintf(const char *fmt, ...) +{ + char *str; + + NV_VSNPRINTF(str, fmt); + + return str; + +} /* nvasprintf() */ + +/* + * nv_append_sprintf() - similar to glib's g_string_append_printf(), except + * instead of operating on a GString it operates on a (char **). Appends a + * formatted string to the end of the dynamically-allocated string pointed to by + * *buf (or the empty string if *buf is NULL), potentially reallocating the + * string in the process. This function only returns on success. + */ +void nv_append_sprintf(char **buf, const char *fmt, ...) +{ + char *prefix, *suffix; + + prefix = *buf; + NV_VSNPRINTF(suffix, fmt); + + if (!prefix) { + *buf = suffix; + } else { + *buf = nvstrcat(prefix, suffix, NULL); + free(prefix); + free(suffix); + } +} + + +/* + * nvfree() - frees memory allocated with nvalloc(), provided + * a non-NULL pointer is provided. + */ +void nvfree(void *s) +{ + if (s) free(s); + +} /* nvfree() */ + + + +/****************************************************************************/ +/* misc */ +/****************************************************************************/ + +/* + * tilde_expansion() - do tilde expansion on the given path name; + * based loosely on code snippets found in the comp.unix.programmer + * FAQ. The tilde expansion rule is: if a tilde ('~') is alone or + * followed by a '/', then substitute the current user's home + * directory; if followed by the name of a user, then substitute that + * user's home directory. + * + * Returns NULL if its argument is NULL; otherwise, returns a malloced + * and tilde-expanded string. + */ + +char *tilde_expansion(const char *str) +{ + char *prefix = NULL; + const char *replace; + char *user, *ret; + struct passwd *pw; + int len; + + if (!str) return NULL; + + if (str[0] != '~') return strdup(str); + + if ((str[1] == '/') || (str[1] == '\0')) { + + /* expand to the current user's home directory */ + + prefix = getenv("HOME"); + if (!prefix) { + + /* $HOME isn't set; get the home directory from /etc/passwd */ + + pw = getpwuid(getuid()); + if (pw) prefix = pw->pw_dir; + } + + replace = str + 1; + + } else { + + /* expand to the specified user's home directory */ + + replace = strchr(str, '/'); + if (!replace) replace = str + strlen(str); + + len = replace - str; + user = malloc(len + 1); + strncpy(user, str+1, len-1); + user[len] = '\0'; + pw = getpwnam(user); + if (pw) prefix = pw->pw_dir; + free (user); + } + + if (!prefix) return strdup(str); + + ret = malloc(strlen(prefix) + strlen(replace) + 1); + strcpy(ret, prefix); + strcat(ret, replace); + + return ret; + +} /* tilde_expansion() */ + + +/* + * nv_prepend_to_string_list() - add a new string to a string list, delimited + * by the given string delimiter. The original list is freed. + */ + +char *nv_prepend_to_string_list(char *list, const char *item, const char *delim) +{ + char *new_list = nvstrcat(item, list ? delim : NULL, list, NULL); + nvfree(list); + return new_list; +} + + +/* + * Read from the given FILE stream until a newline, EOF, or nul + * terminator is encountered, writing data into a growable buffer. + * The eof parameter is set to TRUE when EOF is encountered. In all + * cases, the returned string is null-terminated. + * + * XXX this function will be rather slow because it uses fgetc() to + * pull each character off the stream one at a time; this is done so + * that each character can be examined as it's read so that we can + * appropriately deal with EOFs and newlines. A better implementation + * would use fgets(), but that would still require us to parse each + * read line, checking for newlines or guessing if we hit an EOF. + */ +char *fget_next_line(FILE *fp, int *eof) +{ + char *buf = NULL, *tmpbuf; + char *c = NULL; + int len = 0, buflen = 0; + int ret; + + const int __fget_next_line_len = 32; + + if (eof) { + *eof = FALSE; + } + + while (1) { + if (buflen == len) { /* buffer isn't big enough -- grow it */ + buflen += __fget_next_line_len; + tmpbuf = nvalloc(buflen); + if (buf) { + memcpy(tmpbuf, buf, len); + nvfree(buf); + } + buf = tmpbuf; + c = buf + len; + } + + ret = fgetc(fp); + + if ((ret == EOF) && (eof)) { + *eof = TRUE; + } + + if ((ret == EOF) || (ret == '\n') || (ret == '\0')) { + *c = '\0'; + return buf; + } + + *c = (char) ret; + + len++; + c++; + + } /* while (1) */ + + return NULL; /* should never get here */ +} + +char *nvstrchrnul(char *s, int c) +{ + char *result = strchr(s, c); + if (!result) { + return (s + strlen(s)); + } + return result; +} + +/****************************************************************************/ +/* file helper functions */ +/****************************************************************************/ + +/* + * nv_open() - open(2) wrapper; prints an error message if open(2) + * fails and calls exit(). This function only returns on success. + */ + +int nv_open(const char *pathname, int flags, mode_t mode) +{ + int fd; + fd = open(pathname, flags, mode); + if (fd == -1) { + fprintf(stderr, "Failure opening %s (%s).\n", + pathname, strerror(errno)); + exit(1); + } + return fd; + +} /* nv_name() */ + + + +/* + * nv_get_file_length() - stat(2) wrapper; prints an error message if + * the system call fails and calls exit(). This function only returns + * on success. + */ + +int nv_get_file_length(const char *filename) +{ + struct stat stat_buf; + int ret; + + ret = stat(filename, &stat_buf); + if (ret == -1) { + fprintf(stderr, "Unable to determine '%s' file length (%s).\n", + filename, strerror(errno)); + exit(1); + } + return stat_buf.st_size; + +} /* nv_get_file_length() */ + + + +/* + * nv_set_file_length() - wrapper for lseek() and write(); prints an + * error message if the system calls fail and calls exit(). This + * function only returns on success. + */ + +void nv_set_file_length(const char *filename, int fd, int len) +{ + if ((lseek(fd, len - 1, SEEK_SET) == -1) || + (write(fd, "", 1) == -1)) { + fprintf(stderr, "Unable to set file '%s' length %d (%s).\n", + filename, fd, strerror(errno)); + exit(1); + } +} /* nv_set_file_length() */ + + + +/* + * nv_mmap() - mmap(2) wrapper; prints an error message if mmap(2) + * fails and calls exit(). This function only returns on success. + */ + +void *nv_mmap(const char *filename, size_t len, int prot, int flags, int fd) +{ + void *ret; + + ret = mmap(0, len, prot, flags, fd, 0); + if (ret == (void *) -1) { + fprintf(stderr, "Unable to mmap file %s (%s).\n", + filename, strerror(errno)); + exit(1); + } + return ret; + +} /* nv_mmap() */ + + +/* + * nv_basename() - alternative to basename(3) which avoids differences in + * behavior from different implementations: this implementation never modifies + * the original string, and the return value can always be passed to free(3). + */ + +char *nv_basename(const char *path) +{ + char *last_slash = strrchr(path, '/'); + if (last_slash) { + return strdup(last_slash+1); + } else { + return strdup(path); + } +} + + +/* + * nv_mkdir_recursive() - make a directory and all parent directories as needed. + * dir_list is an optional arguments that if not empty, will be set to a string + * containing a newline separated list of all directories created. + */ +int nv_mkdir_recursive(const char *path, const mode_t mode, + char **error_str, char **dir_list) +{ + char *c, *tmp, ch, *list; + int success = FALSE; + + if (!path || !path[0]) { + return FALSE; + } + + tmp = nvstrdup(path); + remove_trailing_slashes(tmp); + + list = NULL; + + c = tmp; + do { + c++; + if ((*c == '/') || (*c == '\0')) { + ch = *c; + *c = '\0'; + if (!directory_exists(tmp)) { + char *tmplist; + if (mkdir(tmp, mode) != 0) { + *error_str = + nvasprintf("Failure creating directory '%s' : (%s)", + tmp, strerror(errno)); + goto done; + } + /* Prepend the created directory path to a running list */ + if (dir_list) { + tmplist = list; + list = nvstrcat(tmp, "\n", tmplist, NULL); + free(tmplist); + } + } + *c = ch; + } + } while (*c); + + /* Log any created directories */ + if (dir_list && list) { + *dir_list = list; + } + + success = TRUE; + + done: + + if (!dir_list) { + free(list); + } + free(tmp); + return success; +} + + + +/* + * nvdircat() - concatenate path elements, inserting a '/' path separator + * character between each element. + */ + +char *nvdircat(const char *str, ...) +{ + const char *s; + char *result = nvstrdup(""); + va_list ap; + + va_start(ap, str); + + for (s = str; s; s = va_arg(ap, char *)) { + char *oldresult = result; + + result = nvstrcat(result, s == str ? "" : "/", s, NULL); + nvfree(oldresult); + } + + va_end(ap); + + collapse_multiple_slashes(result); + + return result; +} + + +/* + * dirname(3) workalike that abstracts away implementation-specific behavior: + * this function always returns a heap-allocated string that can be passed to + * free(3), and never modifies the contents of the original string. + */ +char *nv_dirname(const char *path) +{ + char *last_slash = strrchr(path, '/'); + if (last_slash) { + return nvstrndup(path, last_slash - path); + } else { + return nvstrdup("."); + } +} + + +/* + * Simple helper function to write the contents of a NUL-terminated string to + * a file. A trailing newline is appended if not already present. + * Returns TRUE on success; FALSE if an error occurred. + */ +int nv_string_to_file(const char *destination, const char *data) +{ + char *dname = nv_dirname(destination); + int written, newline_success = TRUE; + char *error = NULL; + int len, ret; + FILE *fp; + + ret = nv_mkdir_recursive(dname, 0755, &error, NULL); + nvfree(dname); + nvfree(error); + + if (!ret) return FALSE; + + fp = fopen(destination, "w"); + if (!fp) return FALSE; + + len = strlen(data); + written = fwrite(data, 1, len, fp); + if (data[len-1] != '\n') { + if (fwrite("\n", 1, 1, fp) != 1) { + newline_success = FALSE; + } + } + + if (fclose(fp)) return FALSE; + if (chmod(destination, 0644)) return FALSE; + + return written == len && newline_success; +} + + + +/****************************************************************************/ +/* string helper functions */ +/****************************************************************************/ + +/* + * nv_trim_space() - remove any leading and trailing whitespace from a string + * and return a pointer to the modified string. The original string may be + * modified; the returned value should *NOT* be deallocated with free(), since + * it may point somewhere other than the beginning of the original string. If + * the original string was a malloc()ed buffer, that string should be stored + * separately from the returned value of nv_strip_space, and freed. + */ + +char *nv_trim_space(char *string) { + char *ret, *end; + + for (ret = string; *ret && isspace(*ret); ret++); + for (end = ret + strlen(ret) - 1; end >= ret && isspace(*end); end--) { + *end = '\0'; + } + + return ret; +} + +/* + * trim_char() - helper function to remove a character from the initial and + * final positions of a string, and optionally report how many replacements + * were made. The returned value should not be free()d (see nv_trim_space()). + */ + +static char *trim_char(char *string, char trim, int *count) { + int len, replaced = 0; + + if (count) { + *count = 0; + } + + if (string == NULL || trim == '\0') { + return string; + } + + if (string[0] == trim) { + string++; + replaced++; + } + + len = strlen(string); + + if (string[len - 1] == trim) { + string[len - 1] = '\0'; + replaced++; + } + + if (count) { + *count = replaced; + } + + return string; +} + +/* + * nv_trim_char() - remove a character from the initial and final positions of + * a string. The returned value should not be free()d (see nv_trim_space()). + */ + +char *nv_trim_char(char *string, char trim) { + return trim_char(string, trim, NULL); +} + +/* + * nv_trim_char_strict() - remove a character from the initial and final + * positions of a string. If no replacements were made, or if replacements were + * made at both positions, return the modified string. Otherwise, return NULL. + * The returned value should not be free()d (see nv_trim_space()). + */ + +char *nv_trim_char_strict(char *string, char trim) { + int count; + char *trimmed; + + trimmed = trim_char(string, trim, &count); + + if (count == 0 || count == 2) { + return trimmed; + } + + return NULL; +} + +/* + * directory_exists() - test whether the given directory exists + */ + +int directory_exists(const char *dir) +{ + struct stat stat_buf; + + if ((stat (dir, &stat_buf) == -1) || (!S_ISDIR(stat_buf.st_mode))) { + return FALSE; + } else { + return TRUE; + } +} + +/* + * remove_trailing_slashes() - begin at the end of the given string, + * and overwrite slashes with NULL as long as we find slashes. + */ + +void remove_trailing_slashes(char *string) +{ + int len; + + if (string == NULL) { + return; + } + + len = strlen(string); + + while (string[len-1] == '/') { + string[--len] = '\0'; + } + +} + + + +/* + * collapse_multiple_slashes() - remove any/all occurrences of "//" from the + * argument string. + */ + +void collapse_multiple_slashes(char *s) +{ + char *p; + + while ((p = strstr(s, "//")) != NULL) { + p++; /* advance to second '/' */ + while (*p == '/') { + unsigned int i, len; + + len = strlen(p); + for (i = 0; i < len; i++) p[i] = p[i+1]; + } + } +} diff --git a/nvidia-xconfig-540.3.0/common-utils/common-utils.h b/nvidia-xconfig-540.3.0/common-utils/common-utils.h new file mode 100644 index 0000000..dd16266 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/common-utils.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010-2015 NVIDIA Corporation + * + * 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. + */ + +#ifndef __COMMON_UTILS_H__ +#define __COMMON_UTILS_H__ + +#include +#include +#include +#include +#include + +#include "msg.h" + +#if !defined(TRUE) +#define TRUE 1 +#endif + +#if !defined(FALSE) +#define FALSE 0 +#endif + +#define ARRAY_LEN(_arr) (sizeof(_arr) / sizeof(_arr[0])) + +#ifndef NV_MIN +#define NV_MIN(x,y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef NV_MAX +#define NV_MAX(x,y) ((x) > (y) ? (x) : (y)) +#endif + +#define TAB " " +#define BIGTAB " " + +void *nvalloc(size_t size); +char *nvstrcat(const char *str, ...); +void *nvrealloc(void *ptr, size_t size); +char *nvstrdup(const char *s); +char *nvstrndup(const char *s, size_t n); +char *nvstrtolower(char *s); +char *nvstrtoupper(char *s); +char *nvstrchrnul(char *s, int c); +char *nvasprintf(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_append_sprintf(char **buf, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); +void nvfree(void *s); + +char *tilde_expansion(const char *str); +char *nv_prepend_to_string_list(char *list, const char *item, const char *delim); + +char *fget_next_line(FILE *fp, int *eof); + +int nv_open(const char *pathname, int flags, mode_t mode); +int nv_get_file_length(const char *filename); +void nv_set_file_length(const char *filename, int fd, int len); +void *nv_mmap(const char *filename, size_t len, int prot, int flags, int fd); +char *nv_basename(const char *path); +int nv_mkdir_recursive(const char *path, const mode_t mode, + char **error_str, char **log_str); +char *nvdircat(const char *str, ...); +char *nv_dirname(const char *path); +int nv_string_to_file(const char *, const char *); + +char *nv_trim_space(char *string); +char *nv_trim_char(char *string, char trim); +char *nv_trim_char_strict(char *string, char trim); +void remove_trailing_slashes(char *string); +void collapse_multiple_slashes(char *s); + +int directory_exists(const char *dir); + +#if defined(__GNUC__) +# define NV_INLINE __inline__ +#else +# define NV_INLINE +#endif + +/* + * Simple function which encodes a version number, given as major, minor, micro, + * and nano, as a 64-bit unsigned integer. This is defined in an inline function + * rather than as a macro for convenience so it can be examined by the debugger. + * Encoded version numbers can be compared directly in version checks. + */ +static NV_INLINE uint64_t nv_encode_version(unsigned int major, + unsigned int minor, + unsigned int micro, + unsigned int nano) +{ + return (((uint64_t)(nano & 0xFFFF)) | + (((uint64_t)(micro & 0xFFFF)) << 16) | + (((uint64_t)(minor & 0xFFFF)) << 32) | + (((uint64_t)(major & 0xFFFF)) << 48)); +} + +/* + * Wrapper macros for nv_encode_version(). For K in {2,3,4}, NV_VERSIONK() takes + * a K-part version number. + */ +#define NV_VERSION2(major, minor) \ + nv_encode_version(major, minor, 0, 0) +#define NV_VERSION3(major, minor, micro) \ + nv_encode_version(major, minor, micro, 0) +#define NV_VERSION4(major, minor, micro, nano) \ + nv_encode_version(major, minor, micro, nano) + +/* + * Helper enum that can be used for boolean values that might or might not be + * set. Care should be taken to avoid simple boolean testing, as a value of + * NV_OPTIONAL_BOOL_DEFAULT would evaluate as true. + * + * The user is responsible for unconditionally initializing the default value of + * any such booleans to NV_OPTIONAL_BOOL_DEFAULT, before any code path that + * might optionally set their values is executed. + */ + +typedef enum { + NV_OPTIONAL_BOOL_DEFAULT = -1, + NV_OPTIONAL_BOOL_FALSE = FALSE, + NV_OPTIONAL_BOOL_TRUE = TRUE +} NVOptionalBool; + +#define NV_ID_STRING PROGRAM_NAME ": version " NVIDIA_VERSION + +#endif /* __COMMON_UTILS_H__ */ diff --git a/nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.c b/nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.c new file mode 100644 index 0000000..56ba7b3 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2012, 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. + */ + +#include +#include +#include +#include + +#include "nvgetopt.h" +#include "gen-manpage-opts-helper.h" +#include "common-utils.h" + +static void print_option(const NVGetoptOption *o) +{ + char scratch[64]; + const char *s; + int j, len; + + int italics, bold, omitWhiteSpace, firstchar; + + /* if we are going to need the argument, process it now */ + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + if (o->arg_name) { + strcpy(scratch, o->arg_name); + } else { + len = strlen(o->name); + for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]); + scratch[len] = '\0'; + } + } + + printf(".TP\n.BI \""); + /* Print the name of the option */ + /* XXX We should backslashify the '-' characters in o->name. */ + + if (isalpha(o->val)) { + /* '\-c' */ + printf("\\-%c", o->val); + + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + /* ' " "ARG" "' */ + printf(" \" \"%s\" \"", scratch); + } + /* ', ' */ + printf(", "); + } + + /* '\-\-name' */ + printf("\\-\\-%s", o->name); + + /* '=" "ARG' */ + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + printf("=\" \"%s", scratch); + + /* '" "' */ + if ((o->flags & NVGETOPT_IS_BOOLEAN) || + (o->flags & NVGETOPT_ALLOW_DISABLE)) { + printf("\" \""); + } + } + + /* ', \-\-no\-name' */ + if (((o->flags & NVGETOPT_IS_BOOLEAN) && + !(o->flags & NVGETOPT_HAS_ARGUMENT)) || + (o->flags & NVGETOPT_ALLOW_DISABLE)) { + printf(", \\-\\-no\\-%s", o->name); + } + + printf("\"\n"); + + /* Print the option description */ + /* XXX Each sentence should be on its own line! */ + + /* + * Print the option description: write each character one at a + * time (ugh) so that we can special-case a few characters: + * + * '&' : toggles italics on and off + * '^' : toggles bold on and off + * '-' : is backslashified: "\-" + * '\n': resets the first character flag + * '.' : must not be the first character of a line + * '\'': must not be the first character of a line + * + * Trailing whitespace is omitted when italics or bold is on + */ + + italics = FALSE; + bold = FALSE; + omitWhiteSpace = FALSE; + firstchar = TRUE; + + for (s = o->description; s && *s; s++) { + + switch (*s) { + case '&': + if (italics) { + printf("\n"); + } else { + printf("\n.I "); + } + omitWhiteSpace = italics; + firstchar = italics; + italics = !italics; + break; + case '^': + if (bold) { + printf("\n"); + } else { + printf("\n.B "); + } + omitWhiteSpace = bold; + firstchar = bold; + bold = !bold; + break; + case '-': + printf("\\-"); + omitWhiteSpace = FALSE; + firstchar = FALSE; + break; + case ' ': + if (!omitWhiteSpace) { + printf(" "); + firstchar = FALSE; + } + break; + case '\n': + printf("\n"); + omitWhiteSpace = FALSE; + firstchar = TRUE; + break; + case '.': + if (firstchar) { + fprintf(stderr, "Error: *roff can't start a line with '.' " + "If you used '&' or '^' to format text in the " + "description of the '%s' option, please add some " + "text before the end of the sentence, so that a " + "valid manpage can be generated.\n", o->name); + exit(1); + } + /* fall through */ + case '\'': + if (firstchar) { + fprintf(stderr, "Error: *roff can't start a line with '\''. " + "If you started a line with '\'' in the description " + "of the '%s' option, please add some text at the " + "beginning of the sentence, so that a valid manpage " + "can be generated.\n", o->name); + exit(1); + } + /* fall through */ + default: + printf("%c", *s); + omitWhiteSpace = FALSE; + firstchar = FALSE; + break; + } + } + + printf("\n"); +} + +void gen_manpage_opts_helper(const NVGetoptOption *options) +{ + int i; + int has_advanced_options = 0; + + /* Print the "simple" options; i.e. the ones you get with --help. */ + printf(".SH OPTIONS\n"); + for (i = 0; options[i].name; i++) { + const NVGetoptOption *o = &options[i]; + + if (!o->description) { + continue; + } + + if (!(o->flags & NVGETOPT_HELP_ALWAYS)) { + has_advanced_options = 1; + continue; + } + + print_option(o); + } + + if (has_advanced_options) { + /* + * If any exist, print the advanced options; i.e., the ones + * you get with --advanced-help + */ + printf(".SH \"ADVANCED OPTIONS\"\n"); + for (i = 0; options[i].name; i++) { + const NVGetoptOption *o = &options[i]; + + if (!o->description) { + continue; + } + + if (o->flags & NVGETOPT_HELP_ALWAYS) { + continue; + } + + print_option(o); + } + } +} diff --git a/nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.h b/nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.h new file mode 100644 index 0000000..97a2908 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/gen-manpage-opts-helper.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2012, 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. + */ + +#if !defined(__GEN_MANPAGE_OPTS_HELPER_H__) +#define __GEN_MANPAGE_OPTS_HELPER_H__ + +#include "nvgetopt.h" + +void gen_manpage_opts_helper(const NVGetoptOption *options); + +#endif /* __GEN_MANPAGE_OPTS_HELPER_H__ */ diff --git a/nvidia-xconfig-540.3.0/common-utils/msg.c b/nvidia-xconfig-540.3.0/common-utils/msg.c new file mode 100644 index 0000000..e26f6a4 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/msg.c @@ -0,0 +1,428 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * 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. + */ + +#define _GNU_SOURCE // needed for fileno + +#include +#include +#include +#include +#include +#include +#include +#if defined(__sun) +#include +#endif + +#include "msg.h" +#include "common-utils.h" + + +/* + * verbosity, controls output of errors, warnings and other + * information. + */ + +static NvVerbosity __verbosity = NV_VERBOSITY_DEFAULT; + +NvVerbosity nv_get_verbosity(void) +{ + return __verbosity; +} + +void nv_set_verbosity(NvVerbosity level) +{ + __verbosity = level; +} + + +/****************************************************************************/ +/* Formatted I/O functions */ +/****************************************************************************/ + +#define DEFAULT_WIDTH 75 + +static unsigned short __terminal_width = 0; + +/* + * reset_current_terminal_width() - if new_val is zero, then use the + * TIOCGWINSZ ioctl to get the current width of the terminal, and + * assign it the value to __terminal_width. If the ioctl fails, use a + * hardcoded constant. If new_val is non-zero, then use new_val. + */ + +void reset_current_terminal_width(unsigned short new_val) +{ + struct winsize ws; + + if (new_val) { + __terminal_width = new_val; + return; + } + + if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { + __terminal_width = DEFAULT_WIDTH; + } else { + __terminal_width = ws.ws_col - 1; + } +} + + +static void format(FILE *stream, const char *prefix, const char *buf, + const int whitespace) +{ + if (isatty(fileno(stream))) { + int i; + TextRows *t; + + if (!__terminal_width) reset_current_terminal_width(0); + + t = nv_format_text_rows(prefix, buf, __terminal_width, whitespace); + + for (i = 0; i < t->n; i++) fprintf(stream, "%s\n", t->t[i]); + + nv_free_text_rows(t); + } else { + fprintf(stream, "%s%s\n", prefix ? prefix : "", buf); + } +} + + +#define NV_FORMAT(stream, prefix, fmt, whitespace) \ +do { \ + char *buf; \ + NV_VSNPRINTF(buf, fmt); \ + format(stream, prefix, buf, whitespace); \ + free (buf); \ +} while (0) + + +/* + * nv_error_msg() - print an error message, nicely formatted using the + * format() function. + * + * This function should be used for all errors. + */ + +void nv_error_msg(const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_ERROR) return; + + format(stderr, NULL, "", TRUE); + NV_FORMAT(stderr, "ERROR: ", fmt, TRUE); + format(stderr, NULL, "", TRUE); +} /* nv_error_msg() */ + + +/* + * nv_deprecated_msg() - print a deprecation message, nicely formatted using + * the format() function. + * + * This function should be used for all deprecation messages. + */ + +void nv_deprecated_msg(const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_DEPRECATED) return; + + format(stderr, NULL, "", TRUE); + NV_FORMAT(stderr, "DEPRECATED: ", fmt, TRUE); + format(stderr, NULL, "", TRUE); +} + + +/* + * nv_warning_msg() - print a warning message, nicely formatted using + * the format() function. + * + * This function should be used for all warnings. + */ + +void nv_warning_msg(const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_WARNING) return; + + format(stderr, NULL, "", TRUE); + NV_FORMAT(stderr, "WARNING: ", fmt, TRUE); + format(stderr, NULL, "", TRUE); +} /* nv_warning_msg() */ + + +/* + * nv_info_msg() - print an info message, nicely formatted using + * the format() function. + * + * This function should be used to display verbose information. + */ + +void nv_info_msg(const char *prefix, const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_ALL) return; + + NV_FORMAT(stdout, prefix, fmt, TRUE); +} /* nv_info_msg() */ + + +/* + * nv_info_msg_to_file() - Prints the message, just like nv_info_msg() + * using format() the difference is, it prints to any stream defined by + * the corresponding argument. + */ + +void nv_info_msg_to_file(FILE *stream, const char *prefix, const char *fmt, ...) +{ + if (__verbosity < NV_VERBOSITY_ALL) return; + + NV_FORMAT(stream, prefix, fmt, TRUE); +} /* nv_info_msg_to_file() */ + + +/* + * nv_msg() - print a message, nicely formatted using the format() + * function. + * + * This function should be used to display messages independent + * of the verbosity level. + */ + +void nv_msg(const char *prefix, const char *fmt, ...) +{ + NV_FORMAT(stdout, prefix, fmt, TRUE); +} /* nv_msg() */ + + +/* + * nv_msg_preserve_whitespace() - Prints the message, just like nv_msg() + * using format(), the difference is, whitespace characters are not + * skipped during the text processing. + */ + +void nv_msg_preserve_whitespace(const char *prefix, const char *fmt, ...) +{ + NV_FORMAT(stdout, prefix, fmt, FALSE); +} /* nv_msg_preserve_whitespace() */ + + +/* + * XXX gcc's '-ansi' option causes vsnprintf to not be defined, so + * declare the prototype here. + */ + +#if defined(__STRICT_ANSI__) +int vsnprintf(char *str, size_t size, const char *format, + va_list ap); +#endif + + +/****************************************************************************/ +/* TextRows helper functions */ +/****************************************************************************/ + +/* + * nv_format_text_rows() - this function breaks the given string str + * into some number of rows, where each row is not longer than the + * specified width. + * + * If prefix is non-NULL, the first line is prepended with the prefix, + * and subsequent lines are indented to line up with the prefix. + * + * If word_boundary is TRUE, then attempt to only break lines on + * boundaries between words. + */ + +TextRows *nv_format_text_rows(const char *prefix, const char *str, int width, + int word_boundary) +{ + int len, prefix_len, z, w, i; + char *line, *buf, *local_prefix, *a, *b, *c; + TextRows *t; + + /* initialize the TextRows structure */ + + t = (TextRows *) malloc(sizeof(TextRows)); + + if (!t) return NULL; + + t->t = NULL; + t->n = 0; + t->m = 0; + + if (!str) return t; + + buf = strdup(str); + + if (!buf) return t; + + z = strlen(buf); /* length of entire string */ + a = buf; /* pointer to the start of the string */ + + /* initialize the prefix fields */ + + if (prefix) { + prefix_len = strlen(prefix); + local_prefix = strdup(prefix); + } else { + prefix_len = 0; + local_prefix = NULL; + } + + /* adjust the max width for any prefix */ + + w = width - prefix_len; + + do { + /* + * if the string will fit on one line, point b to the end of the + * string + */ + + if (z < w) b = a + z; + + /* + * if the string won't fit on one line, move b to where the + * end of the line should be, and then move b back until we + * find a space; if we don't find a space before we back b all + * the way up to a, just assign b to where the line should end. + */ + + else { + b = a + w; + + if (word_boundary) { + while ((b >= a) && (!isspace(*b))) b--; + if (b <= a) b = a + w; + } + } + + /* look for any newline between a and b, and move b to it */ + + for (c = a; c < b; c++) if (*c == '\n') { b = c; break; } + + /* + * copy the string that starts at a and ends at b, prepending + * with a prefix, if present + */ + + len = b-a; + len += prefix_len; + line = (char *) malloc(len+1); + if (local_prefix) strncpy(line, local_prefix, prefix_len); + strncpy(line + prefix_len, a, len - prefix_len); + line[len] = '\0'; + + /* append the new line to the array of text rows */ + + t->t = (char **) realloc(t->t, sizeof(char *) * (t->n + 1)); + t->t[t->n] = line; + t->n++; + + if (t->m < len) t->m = len; + + /* + * adjust the length of the string and move the pointer to the + * beginning of the new line + */ + + z -= (b - a + 1); + a = b + 1; + + /* move to the first non whitespace character (excluding newlines) */ + + if (word_boundary && isspace(*b)) { + while ((z) && (isspace(*a)) && (*a != '\n')) a++, z--; + } else { + if (!isspace(*b)) z++, a--; + } + + if (local_prefix) { + for (i = 0; i < prefix_len; i++) local_prefix[i] = ' '; + } + + } while (z > 0); + + if (local_prefix) free(local_prefix); + free(buf); + + return t; +} + + +/* + * nv_text_rows_append() - append the given msg to the existing TextRows + */ + +void nv_text_rows_append(TextRows *t, const char *msg) +{ + int len; + + t->t = realloc(t->t, sizeof(char *) * (t->n + 1)); + + if (msg) { + t->t[t->n] = strdup(msg); + len = strlen(msg); + if (t->m < len) t->m = len; + } else { + t->t[t->n] = NULL; + } + + t->n++; +} + +/* + * nv_concat_text_rows() - concatenate two text rows, storing the + * result in t0 + */ + +void nv_concat_text_rows(TextRows *t0, TextRows *t1) +{ + int n, i; + + n = t0->n + t1->n; + + t0->t = realloc(t0->t, sizeof(char *) * n); + + for (i = 0; i < t1->n; i++) { + t0->t[i + t0->n] = strdup(t1->t[i]); + } + + t0->m = NV_MAX(t0->m, t1->m); + t0->n = n; + +} /* nv_concat_text_rows() */ + + +/* + * nv_free_text_rows() - free the TextRows data structure allocated by + * nv_format_text_rows() + */ + +void nv_free_text_rows(TextRows *t) +{ + int i; + + if (!t) return; + for (i = 0; i < t->n; i++) free(t->t[i]); + if (t->t) free(t->t); + free(t); + +} /* nv_free_text_rows() */ + diff --git a/nvidia-xconfig-540.3.0/common-utils/msg.h b/nvidia-xconfig-540.3.0/common-utils/msg.h new file mode 100644 index 0000000..3eae767 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/msg.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2004 NVIDIA Corporation. + * + * 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. + */ + +#ifndef __MSG_H__ +#define __MSG_H__ + +#include +#include + + +/* + * Define a printf format attribute macro. This definition is based on the one + * from Xfuncproto.h, available in the 'xproto' package at + * http://xorg.freedesktop.org/releases/individual/proto/ + */ + +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) +# define NV_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) +#else /* not gcc >= 2.3 */ +# define NV_ATTRIBUTE_PRINTF(x,y) +#endif + + +/* + * NV_VSNPRINTF(): macro that assigns buf using vsnprintf(). This is + * correct for differing semantics of the vsnprintf() return value: + * + * -1 when the buffer is not long enough (glibc < 2.1) + * + * or + * + * the length the string would have been if the buffer had been large + * enough (glibc >= 2.1) + * + * This macro allocates memory for buf; the caller should free it when + * done. + */ + +#define NV_FMT_BUF_LEN 256 + +#define NV_VSNPRINTF(buf, fmt) \ +do { \ + if (!fmt) { \ + (buf) = NULL; \ + } else { \ + va_list ap; \ + int len, current_len = NV_FMT_BUF_LEN; \ + \ + while (1) { \ + (buf) = nvalloc(current_len); \ + \ + va_start(ap, fmt); \ + len = vsnprintf((buf), current_len, (fmt), ap); \ + va_end(ap); \ + \ + if ((len > -1) && (len < current_len)) { \ + break; \ + } else if (len > -1) { \ + current_len = len + 1; \ + } else { \ + current_len += NV_FMT_BUF_LEN; \ + } \ + \ + nvfree(buf); \ + } \ + } \ +} while (0) + + +/* + * verbosity, controls output of errors, warnings and other + * information. + */ + +typedef enum { + NV_VERBOSITY_NONE = 0, /* no errors, warnings or info */ + NV_VERBOSITY_ERROR, /* errors only */ + NV_VERBOSITY_DEPRECATED, /* errors and deprecation messages */ + NV_VERBOSITY_WARNING, /* errors and all warnings */ + NV_VERBOSITY_ALL, /* errors, all warnings and other info */ + NV_VERBOSITY_DEFAULT = NV_VERBOSITY_ALL +} NvVerbosity; + +NvVerbosity nv_get_verbosity(void); +void nv_set_verbosity(NvVerbosity level); + + +/* + * Formatted I/O functions + */ + +void reset_current_terminal_width(unsigned short new_val); + +void nv_error_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_deprecated_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_warning_msg(const char *fmt, ...) NV_ATTRIBUTE_PRINTF(1, 2); +void nv_info_msg(const char *prefix, + const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); +void nv_info_msg_to_file(FILE *stream, + const char *prefix, + const char *fmt, ...) NV_ATTRIBUTE_PRINTF(3, 4); +void nv_msg(const char *prefix, const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); +void nv_msg_preserve_whitespace(const char *prefix, + const char *fmt, ...) NV_ATTRIBUTE_PRINTF(2, 3); + + +/* + * TextRows structure and helper functions + */ + +typedef struct { + char **t; /* the text rows */ + int n; /* number of rows */ + int m; /* maximum row length */ +} TextRows; + +TextRows *nv_format_text_rows(const char *prefix, const char *str, int width, + int word_boundary); +void nv_text_rows_append(TextRows *t, const char *msg); +void nv_concat_text_rows(TextRows *t0, TextRows *t1); +void nv_free_text_rows(TextRows *t); + + +#endif /* __MSG_H__ */ diff --git a/nvidia-xconfig-540.3.0/common-utils/nvgetopt.c b/nvidia-xconfig-540.3.0/common-utils/nvgetopt.c new file mode 100644 index 0000000..5ae3a14 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/nvgetopt.c @@ -0,0 +1,490 @@ +/* + * Copyright (C) 2004-2010 NVIDIA Corporation + * + * 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. + * + * + * nvgetopt.c - portable getopt_long() replacement; removes the need + * for the stupid optstring argument. + */ + +#include +#include +#include +#include +#include + +#include "nvgetopt.h" +#include "common-utils.h" + + +int nvgetopt(int argc, + char *argv[], + const NVGetoptOption *options, + char **strval, + int *boolval, + int *intval, + double *doubleval, + int *disable_val) +{ + char *c, *a, *arg, *name = NULL, *argument=NULL; + int i, found = NVGETOPT_FALSE; + int ret = 0; + int negate = NVGETOPT_FALSE; + int disable = NVGETOPT_FALSE; + int double_dash = NVGETOPT_FALSE; + const NVGetoptOption *o = NULL; + static int argv_index = 0; + + if (strval) *strval = NULL; + if (boolval) *boolval = NVGETOPT_FALSE; + if (intval) *intval = 0; + if (doubleval) *doubleval = 0.0; + if (disable_val) *disable_val = NVGETOPT_FALSE; + + argv_index++; + + /* if no more options, return -1 */ + + if (argv_index >= argc) return -1; + + /* get the argument in question */ + + arg = strdup(argv[argv_index]); + + /* look for "--" or "-" */ + + if ((arg[0] == '-') && (arg[1] == '-')) { + name = arg + 2; + double_dash = NVGETOPT_TRUE; + } else if (arg[0] == '-') { + name = arg + 1; + } else { + fprintf(stderr, "%s: invalid option: \"%s\"\n", argv[0], arg); + goto done; + } + + /* + * if there is an "=" in the string, then assign argument and zero + * out the equal sign so that name will match what is in the + * option table. + */ + + c = name; + while (*c) { + if (*c == '=') { + argument = c + 1; + *c = '\0'; + break; + } + c++; + } + + /* + * if there is no character after '--' then stop processing options. + * if the string is terminated after one character, interpret it + * as a short option. Otherwise, interpret it as a long option. + */ + + if (name[0] == '\0') { + if (double_dash && argument == NULL) { /* option list terminator */ + ret = -1; + goto done; + } + } else if (name[1] == '\0') { /* short option */ + for (i = 0; options[i].name; i++) { + if (options[i].val == name[0]) { + o = &options[i]; + break; + } + } + } else { /* long option */ + for (i = 0; options[i].name; i++) { + const char *tmpname; + int tmp_negate; + + /* + * if this option allows negation by prepending with + * "--no-" (true for IS_BOOLEAN and ALLOW_DISABLE), then + * skip any leading "no-" in the argument + */ + + if ((options[i].flags & (NVGETOPT_IS_BOOLEAN | + NVGETOPT_ALLOW_DISABLE)) && + (name[0] == 'n') && + (name[1] == 'o') && + (name[2] == '-')) { + tmpname = name + 3; + tmp_negate = NVGETOPT_TRUE; + } else { + tmpname = name; + tmp_negate = NVGETOPT_FALSE; + } + + if (strcmp(tmpname, options[i].name) == 0) { + o = &options[i]; + negate = tmp_negate; + break; + } + } + } + + /* + * if we didn't find a match, maybe this is multiple short options + * stored together; is each character a short option? + */ + + if (!o) { + for (c = name; *c; c++) { + found = NVGETOPT_FALSE; + for (i = 0; options[i].name; i++) { + if (options[i].val == *c) { + found = NVGETOPT_TRUE; + break; + } + } + if (!found) break; + } + + if (found) { + + /* + * all characters individually are short options, so + * interpret them that way + */ + + for (i = 0; options[i].name; i++) { + if (options[i].val == name[0]) { + + /* + * don't allow options with arguments to be + * processed in this way + */ + + if (options[i].flags & NVGETOPT_HAS_ARGUMENT) break; + + /* + * remove the first short option from + * argv[argv_index] + */ + + a = argv[argv_index]; + if (a[0] == '-') a++; + if (a[0] == '-') a++; + if (a[0] == '+') a++; + + while (a[0]) { a[0] = a[1]; a++; } + + /* + * decrement argv_index so that we process this + * entry again + */ + + argv_index--; + + o = &options[i]; + break; + } + } + } + } + + /* + * If we still didn't find a match, maybe this is a short option + * with its argument value concatenated (e.g., "-j8"). For now, + * limit this to short options with integer argument values. + */ + if (!o && intval) { + + /* Is the string after the first character an integer? */ + int appendedInteger = NVGETOPT_FALSE; + if ((name[0] != '\0') && (name[1] != '\0')) { + char *endptr; + strtol(name + 1, &endptr, 0); + if (*endptr == '\0') { + /* + * The only characters after the first character are + * parsable by strtol(3). + */ + appendedInteger = NVGETOPT_TRUE; + } + } + + if (appendedInteger) { + for (i = 0; options[i].name; i++) { + if ((options[i].flags & NVGETOPT_INTEGER_ARGUMENT) == 0) { + continue; + } + if (options[i].val == name[0]) { + o = &options[i]; + argument = name + 1; + break; + } + } + } + } + + /* if we didn't find an option, return */ + + if (!o) { + fprintf(stderr, "%s: unrecognized option: \"%s\"\n", argv[0], arg); + goto done; + } + + + /* if the option is boolean, record !negate as the boolean value */ + + if (o->flags & NVGETOPT_IS_BOOLEAN) { + if (boolval) *boolval = !negate; + } + + + /* + * if this option is flagged as "disable-able", then let the + * "--no-" prefix get interpreted to mean that the option should + * be disabled + */ + + if ((o->flags & NVGETOPT_ALLOW_DISABLE) && (negate == NVGETOPT_TRUE)) { + disable = NVGETOPT_TRUE; + } + + + /* + * if the option takes an argument (either string or integer), and + * we haven't already decided to disable the option, then we + * either need to use what was after the "=" in this argv[] entry, + * or we need to pull the next entry off of argv[] + */ + + if ((o->flags & NVGETOPT_HAS_ARGUMENT) && !disable) { + if (argument) { + if (!argument[0]) { + fprintf(stderr, "%s: option \"%s\" requires an " + "argument.\n", argv[0], arg); + goto done; + } + } else { + + /* + * if the argument is optional, and we're either at the + * end of the argv list, or the next argv starts with '-', + * then assume there is no argument for this option + */ + + if ((o->flags & NVGETOPT_ARGUMENT_IS_OPTIONAL) && + ((argv_index == (argc - 1)) || + (argv[argv_index + 1][0] == '-'))) { + argument = NULL; + goto argument_processing_done; + } else { + argv_index++; + if (argv_index >= argc) { + fprintf(stderr, "%s: option \"%s\" requires an " + "argument.\n", argv[0], arg); + goto done; + } + argument = argv[argv_index]; + } + } + + /* argument is now a valid string: parse it */ + + if ((o->flags & NVGETOPT_INTEGER_ARGUMENT) && (intval)) { + + /* parse the argument as an integer */ + + char *endptr; + *intval = (int) strtol(argument, &endptr, 0); + if (*endptr) { + fprintf(stderr, "%s: \"%s\" is not a valid argument for " + "option \"%s\".\n", argv[0], argument, arg); + goto done; + } + } else if ((o->flags & NVGETOPT_STRING_ARGUMENT) && (strval)) { + + /* treat the argument as a string */ + + *strval = strdup(argument); + } else if ((o->flags & NVGETOPT_DOUBLE_ARGUMENT) && (doubleval)) { + + /* parse the argument as a double */ + + char *endptr; + *doubleval = (double) strtod(argument, &endptr); + if (*endptr) { + fprintf(stderr, "%s: \"%s\" is not a valid argument for " + "option \"%s\".\n", argv[0], argument, arg); + goto done; + } + } else { + fprintf(stderr, "%s: error while assigning argument for " + "option \"%s\".\n", argv[0], arg); + goto done; + } + + } else { + + /* if we have an argument when we shouldn't; complain */ + + if (argument) { + fprintf(stderr, "%s: option \"%s\" does not take an argument, but " + "was given an argument of \"%s\".\n", + argv[0], arg, argument); + goto done; + } + } + + argument_processing_done: + + ret = o->val; + + /* fall through */ + + done: + + if (disable_val) *disable_val = disable; + + free(arg); + return ret; + +} /* nvgetopt() */ + + +/* + * cook_description() - the description string may contain text within + * special characters which are interpreted by the manpage generator. + * We want to omit those characters here. + */ + +static char *cook_description(const char *description) +{ + const char *src; + char *s, *dst; + + if (!description) { + return NULL; + } + + s = strdup(description); + + if (!s) { + return NULL; + } + + for (src = description, dst = s; *src; src++) { + if ((*src == '&') || (*src == '^')) { + continue; + } + *dst = *src; + dst++; + } + + *dst = '\0'; + + return s; +} + + +void nvgetopt_print_help(const NVGetoptOption *options, + unsigned int include_mask, + nvgetopt_print_help_callback_ptr callback) +{ + const NVGetoptOption *o; + int i; + + for (i = 0; options[i].name; i++) { + + char *msg = NULL, *arg = NULL, *description = NULL; + + o = &options[i]; + + /* Skip options with no help text */ + if (!o->description) { + continue; + } + + /* skip options who don't have all the bits of include_mask */ + if ((o->flags & include_mask) != include_mask) { + continue; + } + + /* if we are going to need the argument, process it now */ + arg = NULL; + if (o->flags & NVGETOPT_HAS_ARGUMENT) { + if (o->arg_name) { + arg = strdup(o->arg_name); + } else { + char *tmp; + arg = strdup(o->name); + for (tmp = arg; tmp && *tmp; tmp++) { + *tmp = toupper(*tmp); + } + } + } + + msg = NULL; + + /* + * create the long version of the option, possibly with an + * argument; e.g., "--foo" or "--foo=BAR" + */ + if (arg) { + msg = nvstrcat("--", o->name, "=", arg, NULL); + } else { + msg = nvstrcat("--", o->name, NULL); + } + + /* + * prepend the single character version of the option, + * possibly with an argument; e.g., "-f" or "-f BAR" + */ + if (o->val <= UCHAR_MAX && o->val >= 0 && isalpha(o->val)) { + char scratch[16]; + char *tmp; + snprintf(scratch, sizeof(scratch), "%c", o->val); + if (arg) { + tmp = nvstrcat("-", scratch, " ", arg, ", ", msg, NULL); + } else { + tmp = nvstrcat("-", scratch, ", ", msg, NULL); + } + free(msg); + msg = tmp; + } + + /* append the boolean version of the option; e.g., "--no-foo" */ + if (((o->flags & NVGETOPT_IS_BOOLEAN) && + !(o->flags & NVGETOPT_HAS_ARGUMENT)) || + (o->flags & NVGETOPT_ALLOW_DISABLE)) { + char *tmp = nvstrcat(msg, ", --no-", o->name, NULL); + free(msg); + msg = tmp; + } + + /* process the description text */ + description = cook_description(o->description); + + /* give the strings to the caller to format and print */ + callback(msg, description); + + free(msg); + free(arg); + free(description); + } +} diff --git a/nvidia-xconfig-540.3.0/common-utils/nvgetopt.h b/nvidia-xconfig-540.3.0/common-utils/nvgetopt.h new file mode 100644 index 0000000..fb7f666 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/nvgetopt.h @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2004-2010 NVIDIA Corporation + * + * 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. + */ + +#ifndef __NVGETOPT_H__ +#define __NVGETOPT_H__ + +#define NVGETOPT_FALSE 0 +#define NVGETOPT_TRUE 1 + + +/* + * mask of bits not used by nvgetopt in NVGetoptOption::flags; + * these bits are available for use within specific users of + * nvgetopt + */ + +#define NVGETOPT_UNUSED_FLAG_RANGE 0xffff0000 + +/* + * indicates that the option is a boolean value; the presence of the + * option will be interpreted as a TRUE value; if the option is + * prepended with '--no-', the option will be interpreted as a FALSE + * value. On success, nvgetopt will return the parsed boolean value + * through 'boolval'. + */ + +#define NVGETOPT_IS_BOOLEAN 0x0001 + + +/* + * indicates that the option takes an argument to be interpreted as a + * string; on success, nvgetopt will return the parsed string argument + * through 'strval'. + */ + +#define NVGETOPT_STRING_ARGUMENT 0x0002 + + +/* + * indicates that the option takes an argument to be interpreted as an + * integer; on success, nvgetopt will return the parsed integer + * argument through 'intval'. + */ + +#define NVGETOPT_INTEGER_ARGUMENT 0x0004 + + +/* + * indicates that the option takes an argument to be interpreted as + * an double; on success, nvgetopt will return the parsed double + * argument through 'doubleval'. + */ + +#define NVGETOPT_DOUBLE_ARGUMENT 0x0008 + + +/* helper macro */ + +#define NVGETOPT_HAS_ARGUMENT (NVGETOPT_STRING_ARGUMENT | \ + NVGETOPT_INTEGER_ARGUMENT | \ + NVGETOPT_DOUBLE_ARGUMENT) + +/* + * indicates that the option, which normally takes an argument, can be + * disabled if the option is prepended with '--no-', in which case, + * the option does not take an argument. If the option is disabled, + * nvgetopt will return TRUE through 'disable_val'. + * + * Note that NVGETOPT_ALLOW_DISABLE can only be used with options that + * take arguments. + */ + +#define NVGETOPT_ALLOW_DISABLE 0x0010 + + +/* + * indicates that the argument for this option is optional; if no + * argument is present (either the option is already at the end of the + * argv array, or the next option in argv starts with '-'), then the + * option is returned without an argument. + */ + +#define NVGETOPT_ARGUMENT_IS_OPTIONAL 0x0020 + + +/* + * The NVGETOPT_HELP_ALWAYS flag is not used by nvgetopt() itself, but + * is often used by other users of NVGetoptOption tables, who print + * out basic and advanced help. In such cases, OPTION_HELP_ALWAYS is + * used to indicate that the help for the option should always be + * printed. + */ + +#define NVGETOPT_HELP_ALWAYS 0x0040 + + +/* + * Indicates that an option is deprecated. The description field of the + * NVGetoptOption, if set, may be used to store text explaining why the + * option is no longer used. + */ + +#define NVGETOPT_IS_DEPRECATED 0x0080 + +/* + * These flags indicate that a particular boolean or disableable value is no + * longer supported. They can be used together with NVGETOPT_DEPRECATED in + * order to differentiate between deprecated boolean values or enable/disable + * states that will be ignored, and unsupported boolean values or enable/disable + * states that are invalid. + */ + +#define NVGETOPT_DISABLE_IS_INVALID 0x0100 +#define NVGETOPT_ENABLE_IS_INVALID 0x0200 + +typedef struct { + const char *name; + int val; + unsigned int flags; + const char *arg_name; /* not used by nvgetopt() */ + const char *description; /* not used by nvgetopt() */ +} NVGetoptOption; + + +/* + * nvgetopt() - see the glibc getopt_long(3) manpage for usage + * description. Options can be prepended with "--", "-", or "--no-". + * + * A global variable stores the current index into the argv array, so + * subsequent calls to nvgetopt() will advance through argv[]. + * + * On success, the matching NVGetoptOption.val is returned. + * + * If the NVGETOPT_IS_BOOLEAN flag is set, boolval will be set to TRUE + * (or FALSE, if the option string was prepended with "--no-"). + * + * disable_val will be assigned TRUE if the option string was + * prepended with "--no-", otherwise it will be assigned FALSE. + * + * If an argument is successfully parsed, one of strval, intval, or + * doubleval will be assigned, based on which of + * NVGETOPT_STRING_ARGUMENT, NVGETOPT_INTEGER_ARGUMENT, or + * NVGETOPT_DOUBLE_ARGUMENT is set in the option's flags. If strval + * is assigned to a non-NULL value by nvgetopt, then it is the + * caller's responsibility to free the string when done with it. + * + * On failure, an error is printed to stderr, and 0 is returned. + * + * When there are no more options to parse, -1 is returned. + */ + +int nvgetopt(int argc, + char *argv[], + const NVGetoptOption *options, + char **strval, + int *boolval, + int *intval, + double *doubleval, + int *disable_val); + +/* + * nvgetopt_print_help() - print a help message for each option in the + * provided NVGetoptOption array. This is useful for a utility's + * "--help" output. + * + * Options will only be printed if they have every bit set that + * include_mask includes. + * + * For each option, the provided callback function will be called with + * two strings: a name string that lists the option's name, and a + * description string for the option. The callback function is + * responsible for actually printing these strings. Examples: + * + * name = "-v, --version"; + * description = "Print usage information for the common commandline " + * "options and exit."; + */ + +typedef void nvgetopt_print_help_callback_ptr(const char *name, + const char *description); + +void nvgetopt_print_help(const NVGetoptOption *options, + unsigned int include_mask, + nvgetopt_print_help_callback_ptr callback); + +#endif /* __NVGETOPT_H__ */ diff --git a/nvidia-xconfig-540.3.0/common-utils/nvpci-utils.c b/nvidia-xconfig-540.3.0/common-utils/nvpci-utils.c new file mode 100644 index 0000000..62946d2 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/nvpci-utils.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2021 NVIDIA Corporation + * + * 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. + */ + +#include "nvpci-utils.h" + +/* + * libpciaccess stores the device class in bits 16-23, subclass in 8-15, and + * interface in bits 0-7 of dev->device_class. We care only about the class + * and subclass. + */ +const uint32_t PCI_CLASS_DISPLAY_VGA = 0x30000; +const uint32_t PCI_CLASS_SUBCLASS_MASK = 0xffff00; + +/* + * nvpci_find_gpu_by_vendor() - use libpciaccess to find all VGA and 3D PCI + * devices matching the passed-in vendor_id (which may be set to PCI_MATCH_ANY). + * The caller is responsible for calling pci_system_init() before using this + * function, and pci_system_cleanup() when libpciaccess is no longer needed. + */ +struct pci_device_iterator *nvpci_find_gpu_by_vendor(uint32_t vendor_id) +{ + const struct pci_id_match match = { + .vendor_id = vendor_id, + .device_id = PCI_MATCH_ANY, + .subvendor_id = PCI_MATCH_ANY, + .subdevice_id = PCI_MATCH_ANY, + .device_class = PCI_CLASS_DISPLAY_VGA, + /* + * Ignore bit 1 of the subclass, to allow both 0x30000 (VGA controller) + * and 0x30200 (3D controller). + */ + .device_class_mask = PCI_CLASS_SUBCLASS_MASK & ~0x200, + }; + + return pci_id_match_iterator_create(&match); +} + +/* + * nvpci_dev_is_vga() - test whether the passed-in struct pci_device* has the + * VGA device class 0x0300 (and not 3D class 0x0302). + */ +int nvpci_dev_is_vga(struct pci_device *dev) +{ + return (dev->device_class & PCI_CLASS_SUBCLASS_MASK) == + PCI_CLASS_DISPLAY_VGA; +} diff --git a/nvidia-xconfig-540.3.0/common-utils/nvpci-utils.h b/nvidia-xconfig-540.3.0/common-utils/nvpci-utils.h new file mode 100644 index 0000000..9813e90 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/nvpci-utils.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 NVIDIA Corporation + * + * 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. + */ + +#ifndef __NVPCI_UTILS_H__ +#define __NVPCI_UTILS_H__ + +#include + +#define NV_PCI_VENDOR_ID 0x10de + +struct pci_device_iterator *nvpci_find_gpu_by_vendor(uint32_t vendor_id); +int nvpci_dev_is_vga(struct pci_device *dev); + +#endif /* __NVPCI_UTILS_H__ */ diff --git a/nvidia-xconfig-540.3.0/common-utils/src.mk b/nvidia-xconfig-540.3.0/common-utils/src.mk new file mode 100644 index 0000000..bb1e1d3 --- /dev/null +++ b/nvidia-xconfig-540.3.0/common-utils/src.mk @@ -0,0 +1,30 @@ +# makefile fragment included by nvidia-xconfig, nvidia-settings, and nvidia-installer + +# the including makefile should set this if the relevant program uses pciaccess +COMMON_UTILS_PCIACCESS ?= + +COMMON_UTILS_SRC += nvgetopt.c +COMMON_UTILS_SRC += common-utils.c +COMMON_UTILS_SRC += msg.c + +COMMON_UTILS_EXTRA_DIST += nvgetopt.h +COMMON_UTILS_EXTRA_DIST += common-utils.h +COMMON_UTILS_EXTRA_DIST += msg.h +COMMON_UTILS_EXTRA_DIST += src.mk + +# only build nvpci-utils.c for programs that actually use libpciaccess, to +# prevent other programs from needing to set the right CFLAGS/LDFLAGS for code +# they won't use. Otherwise, just package it in the source tarball. +ifneq ($(COMMON_UTILS_PCIACCESS),) + COMMON_UTILS_SRC += nvpci-utils.c +else + COMMON_UTILS_EXTRA_DIST += nvpci-utils.c +endif +COMMON_UTILS_EXTRA_DIST += nvpci-utils.h + +# gen-manpage-opts-helper.c is listed in EXTRA_DIST, rather than SRC, +# because it is not compiled into the utilities themselves, but used +# when building the utility's gen-manpage-opts +COMMON_UTILS_EXTRA_DIST += gen-manpage-opts-helper.c +COMMON_UTILS_EXTRA_DIST += gen-manpage-opts-helper.h + diff --git a/nvidia-xconfig-540.3.0/dist-files.mk b/nvidia-xconfig-540.3.0/dist-files.mk new file mode 100644 index 0000000..b52cdc5 --- /dev/null +++ b/nvidia-xconfig-540.3.0/dist-files.mk @@ -0,0 +1,51 @@ +# +# nvidia-xconfig: A tool for manipulating X config files, +# specifically for use by the NVIDIA Linux graphics driver. +# +# Copyright (C) 2008 NVIDIA Corporation. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms and conditions of the GNU General Public License, +# version 2, as published by the Free Software Foundation. +# +# This program is distributed in the hope it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +############################################################################## +# define the list of files that should be distributed in the +# nvidia-xconfig tarball; this is used by the NVIDIA driver build +# when packaging the tarball, and by the nvidia-xconfig makefile when +# building nvidia-xconfig. +# +# Defines SRC and DIST_FILES +############################################################################## + +XCONFIG_PARSER_DIR = XF86Config-parser + +include $(XCONFIG_PARSER_DIR)/src.mk + +SRC := $(addprefix $(XCONFIG_PARSER_DIR)/,$(XCONFIG_PARSER_SRC)) +SRC += util.c +SRC += nvidia-xconfig.c +SRC += make_usable.c +SRC += multiple_screens.c +SRC += tree.c +SRC += options.c +SRC += lscf.c +SRC += query_gpu_info.c +SRC += extract_edids.c + +DIST_FILES := $(SRC) +DIST_FILES += $(addprefix $(XCONFIG_PARSER_DIR)/,$(XCONFIG_PARSER_EXTRA_DIST)) +DIST_FILES += nvidia-xconfig.h +DIST_FILES += option_table.h +DIST_FILES += nvidia-xconfig.1.m4 +DIST_FILES += gen-manpage-opts.c +DIST_FILES += dist-files.mk +DIST_FILES += COPYING diff --git a/nvidia-xconfig-540.3.0/extract_edids.c b/nvidia-xconfig-540.3.0/extract_edids.c new file mode 100644 index 0000000..0dac31a --- /dev/null +++ b/nvidia-xconfig-540.3.0/extract_edids.c @@ -0,0 +1,1105 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2006 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * extract-edids.c + * + * This source file gives us the means to extract EDIDs from verbose X + * log files or from .txt files. A verbose log will contain a raw EDID + * byte dump like this: + * + * (--) NVIDIA(0): Raw EDID bytes: + * (--) NVIDIA(0): + * (--) NVIDIA(0): 00 ff ff ff ff ff ff 00 5a 63 47 4b fc 27 00 00 + * (--) NVIDIA(0): 0f 0a 01 02 9e 1e 17 64 ee 04 85 a0 57 4a 9b 26 + * (--) NVIDIA(0): 12 50 54 00 08 00 01 01 01 01 01 01 01 01 01 01 + * (--) NVIDIA(0): 01 01 01 01 01 01 64 19 00 40 41 00 26 30 18 88 + * (--) NVIDIA(0): 36 00 30 e4 10 00 00 18 00 00 00 ff 00 47 4b 30 + * (--) NVIDIA(0): 31 35 31 30 32 33 36 0a 20 20 00 00 00 fc 00 56 + * (--) NVIDIA(0): 69 65 77 53 6f 6e 69 63 20 56 50 44 00 00 00 fc + * (--) NVIDIA(0): 00 31 35 30 0a 20 20 20 20 20 20 20 20 20 00 ce + * (--) NVIDIA(0): + * + * The added possibilities for the X log are, that the log file contains + * timestamps along with the raw EDID byte dump like this: + * + * (--) Dec 29 15:27:13 NVIDIA(0): 00 ff ff ff ff ff ff 00 5a 63 47 4b fc 27 00 00 + * (--) Dec 29 15:27:13 NVIDIA(0): 0f 0a 01 02 9e 1e 17 64 ee 04 85 a0 57 4a 9b 26 + * + * In the above example, we see log for the 0'th screen. But there + * can be up to 16 screens, so we can expect the X log content as below: + * + * (--) Dec 29 15:27:13 NVIDIA(13): 00 ff ff ff ff ff ff 00 5a 63 47 4b fc 27 00 00 + * (--) Dec 29 15:27:13 NVIDIA(13): 0f 0a 01 02 9e 1e 17 64 ee 04 85 a0 57 4a 9b 26 + * + * Where "NVIDIA(13)" indicates 13'th screen. We need to process both + * timestamps & screen numbers from (0-15), while parsing the X log file + * for raw EDID bytes. We have special states + * (STATE_LOOKING_FOR_START_OF_LABEL & STATE_LOOKING_FOR_SCREEN_NUMBER_IN_LABEL) + * for handling these special cases. + * + * Note that in some cases the label could have the form + * "NVIDIA(GPU-0)" rather than "NVIDIA(0)". + + * A .txt file will contain a raw EDID byte dump like this: + * + * 00 FF FF FF FF FF FF 00-06 10 F4 01 01 01 01 01 ................ + * 27 08 01 01 28 1F 17 96-E8 44 E4 A1 57 4A 97 23 '...(....D..WJ.# + * 19 4F 57 BF EE 00 01 01-01 01 01 01 01 01 01 01 .OW............. + * 01 01 01 01 01 01 64 19-00 40 41 00 26 30 18 88 ......d..@A.&0.. + * 36 00 33 E6 10 00 00 18-40 1F 00 30 41 00 24 30 6.3.....@..0A.$0 + * 20 60 33 00 33 E6 10 00-00 18 00 00 00 FD 00 38 `3.3..........8 + * 4C 1F 3D 08 00 0A 20 20-20 20 20 20 00 00 00 FC L.=... .... + * 00 41 70 70 6C 65 53 74-75 64 69 6F 0A 20 00 88 .AppleStudio. .. + * + * EDID Version : 1.1 + * + * We read a log file or a .txt file, identify and read any EDID(s) contained + * in the file, and then write the EDID bytes to edid.bin files (just + * like what nvidia-settings can capture for display devices running + * on the current X server). + * + * This is useful for NVIDIA engineers to simulate users' display + * environments, based on a verbose nvidia-bug-report.log or X log or a .txt + * file. This utility is included in nvidia-xconfig, since maybe users will + * find use for this, too. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* bzero() */ + +#include "nvidia-xconfig.h" +#include "msg.h" + + +#define NIBBLE_TO_HEX(n) (((n) <= 9) ? ('0' + (n)) : ('a' - 0xa + (n))) + +#define HEX_TO_NIBBLE(n) \ + ((((n) >= '0') && ((n) <= '9')) ? ((n) - '0') : \ + ((((n) >= 'a') && ((n) <= 'f')) ? (((n) - 'a') + 10) : \ + ((((n) >= 'A') && ((n) <= 'F')) ? (((n) - 'A') + 10) : 0))) \ + +#define IS_HEX(n) ((((n) >= '0') && ((n) <= '9')) || \ + (((n) >= 'a') && ((n) <= 'f')) || \ + (((n) >= 'A') && ((n) <= 'F'))) + +#define TRUE 1 +#define FALSE 0 + +#define EDID_OUTPUT_FILE_NAME "edid.bin" + +#define LOG_FILE 10 +#define TEXT_FILE 20 +#define UNKNOWN_FILE 30 + +typedef struct { + int size; + unsigned char *bytes; + char *name; +} EdidRec, *EdidPtr; + +typedef struct { + char *start; + size_t length; + char *current; +} FileRec, *FilePtr; + + +static int findFileType(FilePtr pFile); + +static EdidPtr findEdidforLogFile(FilePtr pFile); +static EdidPtr findEdidforTextFile(FilePtr pFile); + +static int findEdidHeaderforLogFile(FilePtr pFile); +static int readEdidDataforLogFile(FilePtr pFile, EdidPtr pEdid); +static int readEdidFooterforLogFile(FilePtr pFile, EdidPtr pEdid); + +static int findEdidfooterforTextFile(FilePtr pFile); +static int readEdidDataforTextFile(FilePtr pFile, EdidPtr pEdid); +static int readMonitorNameforTextFile(FilePtr pFile, EdidPtr pEdid); + +static char *findFileName(char *option); +static int writeEdidFile(EdidPtr pEdid, char *filename); + +static void freeEdid(EdidPtr pEdid); + +/* + * Moves FilePtr::current to the end of the next occurrence of the + * specified string within the file. Return TRUE if the string is + * found in the file; return FALSE otherwise. + */ + +static inline int moveFilePointerPastString(FilePtr pFile, const char *s) +{ + size_t len = strlen(s); + + while (((pFile->current - pFile->start) + len) <= pFile->length) { + + if (strncmp(pFile->current, s, len) == 0) { + + pFile->current += len; + return TRUE; + } + pFile->current++; + } + return FALSE; +} + + +/* + * extract_edids() - see description at the top of this file + */ + +int extract_edids(Options *op) +{ + int fd = -1, ret, fileType, funcRet = FALSE; + char *filename; + + struct stat stat_buf; + + FileRec file; + EdidPtr pEdid, *pEdids; + int nEdids, i; + + nEdids = 0; + pEdid = NULL; + pEdids = NULL; + + memset(&file, 0, sizeof(FileRec)); + file.start = (void *) -1; + + /* open the file and get its length */ + + fd = open(op->extract_edids_from_file, O_RDONLY); + + if (fd == -1) { + nv_error_msg("Unable to open file \"%s\".", op->extract_edids_from_file); + goto done; + } + + ret = fstat(fd, &stat_buf); + + if (ret == -1) { + nv_error_msg("Unable to get length of file \"%s\".", + op->extract_edids_from_file); + goto done; + } + + file.length = stat_buf.st_size; + + if (file.length == 0) { + nv_error_msg("File \"%s\" is empty.", op->extract_edids_from_file); + goto done; + } + + /* mmap the file */ + + file.start = mmap(0, file.length, PROT_READ, + MAP_SHARED, fd, 0); + + if (file.start == (void *) -1) { + nv_error_msg("Unable to map file \"%s\".", op->extract_edids_from_file); + goto done; + } + + /* start parsing at the start of file */ + + file.current = file.start; + + /* check for the file type(log or .txt) */ + + fileType = findFileType(&file); + + /* if the file does not contain any edid information, goto done */ + + if (fileType == UNKNOWN_FILE) { + funcRet = TRUE; + goto done; + } + + if (fileType == LOG_FILE) { + file.current = file.start; + } + + /* scan through the whole file, and build a list of pEdids */ + + while (1) { + + if (fileType == LOG_FILE) { + + pEdid = findEdidforLogFile(&file); + + } + + if (fileType == TEXT_FILE) { + + pEdid = findEdidforTextFile(&file); + + } + + if (!pEdid) break; + + pEdids = nvrealloc(pEdids, sizeof(pEdids) * (nEdids + 1)); + + pEdids[nEdids] = pEdid; + nEdids++; + + /* Only one edid in a .txt file */ + + if (fileType == TEXT_FILE) break; + } + + /* fall through to the 'done' label */ + + funcRet = TRUE; + + done: + + /* unmap and close the file */ + + if (file.start != (void *) -1) { + munmap(file.start, file.length); + } + + if (fd != -1) { + close(fd); + } + + + /* write the EDIDs to file */ + + /* + * determine the base filename; this is what we pass to + * writeEdidFile; it will unique-ify from there + */ + + nv_info_msg(NULL, ""); + nv_info_msg(NULL, "Found %d EDID%s in \"%s\".", + nEdids, (nEdids == 1) ? "": "s", op->extract_edids_from_file); + + filename = findFileName(op->extract_edids_output_file); + + for (i = 0; i < nEdids; i++) { + + pEdid = pEdids[i]; + + funcRet = writeEdidFile(pEdid, filename); + + freeEdid(pEdid); + } + + if (pEdids) nvfree(pEdids); + + nvfree(filename); + + nv_info_msg(NULL, ""); + + return funcRet; + +} // extract_edids() + +/* + * findFileType() - scan through the pFile to determine the file type + * file type can be LOG_FILE, TEXT_FILE, UNKNOWN_FILE(file with no EDID) + */ + +static int findFileType(FilePtr pFile) +{ + if (findEdidHeaderforLogFile(pFile)) return LOG_FILE; + + if (findEdidfooterforTextFile(pFile)) return TEXT_FILE; + + return UNKNOWN_FILE; + +} // findFileType() + +/* + * findEdid() - scan through pFile for an EDID header, if we find one, + * parse the EDID data and footer. On success, return a newly + * allocated pEdid data structure. On failure, return NULL. + */ + +static EdidPtr findEdidforLogFile(FilePtr pFile) +{ + EdidPtr pEdid = nvalloc(sizeof(EdidRec)); + + if (!findEdidHeaderforLogFile(pFile)) goto fail; + + if (!readEdidDataforLogFile(pFile, pEdid)) goto fail; + + if (!readEdidFooterforLogFile(pFile, pEdid)) goto fail; + + return pEdid; + + fail: + + freeEdid(pEdid); + + return NULL; + +} // findEdidforLogFile() + +/* + * scan through the pFile for EDID data and Monitor name. + */ + +static EdidPtr findEdidforTextFile(FilePtr pFile) +{ + EdidPtr pEdid = nvalloc(sizeof(EdidRec)); + + if (!readEdidDataforTextFile(pFile,pEdid)) goto fail; + if (!readMonitorNameforTextFile(pFile, pEdid)) goto fail; + + return pEdid; + + fail: + + freeEdid(pEdid); + + return NULL; + +} // findEdidforTextFile() + + +/* + * findEdidHeader() - scan the mmapped file, starting at + * 'pFile->current', for the string "Raw EDID bytes:". If we find the + * string, return TRUE, and leave pFile->current pointing to the first + * character past the string. If we reach the end of the mmapped + * file, return FALSE. + */ + +static int findEdidHeaderforLogFile(FilePtr pFile) +{ + return moveFilePointerPastString(pFile, "Raw EDID bytes:"); + +} // findEdidHeaderforLogFile() + + +/* + * findLogFileLineLabel() - scan the mmapped file, starting at + * 'pFile->current', for the string "NVIDIA(". If we find the + * string, return TRUE, and leave pFile->current pointing to the last + * character of the string. If we reach the end of the mmapped + * file, return FALSE. + * + * Note we intentionally leave pFile->current pointing to the last + * character of the string, because the readEdidDataforLogFile() + * state machine will move pFile->current forward one character when + * findLogFileLineLabel() succeeds. + * + * This handles both "NVIDIA(#)" and "NVIDIA(GPU-#)". + */ + +static int findLogFileLineLabel(FilePtr pFile) +{ + while ((pFile->current - pFile->start) <= pFile->length) { + + const char *gpuTag = "NVIDIA(GPU"; + const char *screenTag = "NVIDIA("; + + size_t remainder = pFile->length - (pFile->current - pFile->start); + + if ((remainder > strlen(gpuTag)) && + (strncmp(pFile->current, gpuTag, strlen(gpuTag)) == 0)) { + + pFile->current += strlen(gpuTag); + return TRUE; + } + + if ((remainder > strlen(screenTag)) && + (strncmp(pFile->current, screenTag, strlen(screenTag)) == 0)) { + + pFile->current += strlen(screenTag); + return TRUE; + } + pFile->current++; + } + + return FALSE; + +} // findLogFileLineLabel() + + +/* + * readEdidData() - start parsing at pFile->current for the EDID + * string; it is assumed that pFile was advanced to the correct + * position by findEdidHeader() (i.e., we should be immediately after + * "Raw EDID bytes:"). We use a state machine to look for the lower + * and upper nibbles of each EDID byte, and to advance past the label, + * that looks something like "(--) NVIDIA(0):". + */ + +#define STATE_LOOKING_FOR_TOP_NIBBLE 0 +#define STATE_LOOKING_FOR_BOTTOM_NIBBLE 1 +#define STATE_LOOKING_FOR_START_OF_LABEL 2 +#define STATE_LOOKING_FOR_SCREEN_NUMBER_IN_LABEL 3 +#define STATE_LOOKING_FOR_END_OF_LABEL 4 + +#define MAX_EDID_SIZE 4096 + +static int readEdidDataforLogFile(FilePtr pFile, EdidPtr pEdid) +{ + int state; + + unsigned char pData[MAX_EDID_SIZE]; + int k; + + char c; + + /* clear the scratch EDID data */ + + bzero(pData, MAX_EDID_SIZE); + + /* + * start the parsing state machine by looking for the upper nibble + * of the first byte in the EDID + */ + + state = STATE_LOOKING_FOR_TOP_NIBBLE; + k = 0; + + while (1) { + + c = pFile->current[0]; + + switch (state) { + + case STATE_LOOKING_FOR_TOP_NIBBLE: + + /* if we hit a newline, transition to label parsing */ + + if (c == '\n') { + state = STATE_LOOKING_FOR_START_OF_LABEL; + goto nextChar; + } + + /* skip white space; keep looking for top nibble */ + + if (isspace(c)) { + state = STATE_LOOKING_FOR_TOP_NIBBLE; + goto nextChar; + } + + /* + * if we found a hex value, treat it as upper nibble, then + * look for lower nibble + */ + + if (IS_HEX(c)) { + pData[k] |= ((HEX_TO_NIBBLE(c)) << 4); + state = STATE_LOOKING_FOR_BOTTOM_NIBBLE; + goto nextChar; + } + + /* + * if we hit anything else, we have reached the end of the + * EDID: exit the state machine. + */ + + goto done; + break; + + case STATE_LOOKING_FOR_BOTTOM_NIBBLE: + + /* + * if we found a hex value, treat it as the lower nibble, + * then look for the upper nibble of the next byte + */ + + if (IS_HEX(c)) { + pData[k] |= (HEX_TO_NIBBLE(c)); + state = STATE_LOOKING_FOR_TOP_NIBBLE; + k++; + if (k >= MAX_EDID_SIZE) goto fail; + goto nextChar; + } + + goto fail; /* anything else is an error */ + + break; + + case STATE_LOOKING_FOR_START_OF_LABEL: + + /* + * look for the "NVIDIA(" portion of the label; if we find + * it, transition to looking for the screen number within the + * label; if we don't find the label, consider it an error + */ + + if (findLogFileLineLabel(pFile)) { + state = STATE_LOOKING_FOR_SCREEN_NUMBER_IN_LABEL; + goto nextChar; + } else { + goto fail; + } + break; + + case STATE_LOOKING_FOR_SCREEN_NUMBER_IN_LABEL: + + /* + * if we find a digit, this is part of the screen number; + * continue searching for more of the screen number + */ + + if (isdigit(c)) { + goto nextChar; + } + + /* + * if we find a closing parenthesis, then we are at the end of the + * label's screen number; transition to looking for the end + * of the label + */ + + if (c == ')') { + state = STATE_LOOKING_FOR_END_OF_LABEL; + goto nextChar; + } + + goto fail; /* anything else is an error */ + + break; + + case STATE_LOOKING_FOR_END_OF_LABEL: + + /* + * if we find a colon, then we are at the end of the + * label; transition to looking for the upper nibble of + * the next EDID byte + */ + + if (c == ':') { + state = STATE_LOOKING_FOR_TOP_NIBBLE; + goto nextChar; + } + + goto fail; /* anything else is an error */ + + break; + + default: + + goto fail; /* should never get here */ + + break; + } + + nextChar: + + /* + * if we are at the end of the mapping without hitting our + * exit condition, fail + */ + + if ((pFile->current - pFile->start) >= pFile->length) goto fail; + + /* move to the next character, and run the state machine again */ + + pFile->current++; + + } /* while(1) */ + + done: + + /* we are done parsing the EDID, save what we have into pEdid */ + + if (k <= 0) goto fail; + + pEdid->size = k; + pEdid->bytes = nvalloc(k); + + memcpy(pEdid->bytes, pData, k); + + return TRUE; + + fail: + + return FALSE; + +} // readEdidDataforLogFile() + +/* + * read EDID data for the .txt file; pFile->current gives the starting + * position of the EDID bytes, which is same as file starting position. + * We use a state machine to look for the lower and upper nibbles of each + * EDID byte, and to advance past the label. + */ + +static int readEdidDataforTextFile(FilePtr pFile, EdidPtr pEdid) +{ + int state; + + unsigned char pData[MAX_EDID_SIZE]; + int k; + + char c; + + /* clear the scratch EDID data */ + + bzero(pData, MAX_EDID_SIZE); + + /* + * start the parsing state machine by looking for the upper nibble + * of the first byte in the EDID + */ + + state = STATE_LOOKING_FOR_TOP_NIBBLE; + k = 0; + + while (1) { + + c = pFile->current[0]; + + switch (state) { + + case STATE_LOOKING_FOR_TOP_NIBBLE: + + /* + * if we found a hex value, treat it as upper nibble, then + * look for lower nibble + */ + + if (IS_HEX(c)) { + pData[k] |= ((HEX_TO_NIBBLE(c)) << 4); + state = STATE_LOOKING_FOR_BOTTOM_NIBBLE; + goto nextChar; + } + + /* skip '-' and keep looking for top nibble */ + + if (c == '-') { + state = STATE_LOOKING_FOR_TOP_NIBBLE; + goto nextChar; + } + + /* + * if two consecutive white space, change lebel. + * if one white space, skip it. + */ + + if (isspace(c)) { + + if (isspace(pFile->current[1])) { + state = STATE_LOOKING_FOR_END_OF_LABEL; + goto nextChar; + } else { + state = STATE_LOOKING_FOR_TOP_NIBBLE; + goto nextChar; + } + } + + goto fail; /* anything else is an error */ + + break; + + case STATE_LOOKING_FOR_BOTTOM_NIBBLE: + + /* + * if we found a hex value, treat it as the lower nibble, + * then look for the upper nibble of the next byte + */ + + if (IS_HEX(c)) { + pData[k] |= (HEX_TO_NIBBLE(c)); + state = STATE_LOOKING_FOR_TOP_NIBBLE; + k++; + if (k >= MAX_EDID_SIZE) goto fail; + goto nextChar; + } + + goto fail; /* anything else is an error */ + + break; + + case STATE_LOOKING_FOR_END_OF_LABEL: + + /* if we found two consecutive '\r\n', then the reding of EDID + * information is complete. if only one '\r\n', then change the + * state. + */ + + if (c == '\r' && pFile->current[1] == '\n') { + + if (pFile->current[2] == '\r' && pFile->current[3] == '\n') { + goto done; + } else { + state = STATE_LOOKING_FOR_TOP_NIBBLE; + goto nextChar; + } + } + + /* skip the white space */ + + if (isspace(c)) { + + state = STATE_LOOKING_FOR_END_OF_LABEL; + goto nextChar; + + } + + break; + + default: + + goto fail; + + break; + } + + nextChar: + + /* + * if we are at the end of the mapping without hitting our + * exit condition, fail + */ + + if ((pFile->current - pFile->start) >= pFile->length) goto fail; + + pFile->current++; + } /* while(1) */ + + done: + + /* we are done parsing the EDID, save what we have into pEdid */ + + if (k <= 0) goto fail; + + pEdid->size = k; + pEdid->bytes = nvalloc(k); + + memcpy(pEdid->bytes, pData, k); + + return TRUE; + + fail: + + return FALSE; + +} // readEdidDataforTextFile() + +/* + * readEdidFooter() - the optional EDID footer is in the form: + * + * --- End of EDID for [dpy name] --- + * + * Parse the footer to get the dpy name. If a footer is present, + * pFile->current is expected to point at the start of it. On + * success, pEdid->name is assigned and TRUE is returned. On failure, + * FALSE is returned. + */ + +static int readEdidFooterforLogFile(FilePtr pFile, EdidPtr pEdid) +{ + char *begin; + int len, ret; + const char *edidFooterStart = "--- End of EDID for "; + const char *edidFooterEnd = " ---"; + + /* check that the mapping is large enough */ + + if (((pFile->current - pFile->start) + strlen(edidFooterStart)) > + pFile->length) { + return FALSE; + } + + /* check whether the footer text is there */ + + if (strncmp(pFile->current, edidFooterStart, strlen(edidFooterStart)) != 0) { + + /* if not, we do not know the name of the display device */ + + pEdid->name = strdup("unknown"); + + return TRUE; + } + + /* skip past the start */ + + pFile->current += strlen(edidFooterStart); + + begin = pFile->current; + + /* search for the end of the expected text */ + + ret = moveFilePointerPastString(pFile, edidFooterEnd); + + if (!ret) { + return FALSE; + } + + /* + * moveFilePointerPastString() will have moved current past the + * end of the footer + */ + + len = pFile->current - begin - strlen(edidFooterEnd); + + /* make sure the name length seems reasonable */ + + if ((len > 512) || (len < 1)) { + return FALSE; + } + + pEdid->name = nvalloc(len + 1); + + strncpy(pEdid->name, begin, len); + pEdid->name[len] = '\0'; + + return TRUE; + +} // readEdidFooterforLogFile() + +/* + * read Edid Footer i.e. "EDID Version". + * this information is used to check whether the .txt file contains + * any edid information or not + */ + +static int findEdidfooterforTextFile(FilePtr pFile) +{ + return moveFilePointerPastString(pFile, "EDID Version"); + +} // findEdidfooterforTextFile() + +/* read the monitor information */ + +static int readMonitorNameforTextFile(FilePtr pFile, EdidPtr pEdid) +{ + char *begin; + int len; + + int ret = moveFilePointerPastString(pFile, "Monitor Name"); + + if (!ret) { + return FALSE; + } + + /* search for start of the expected text */ + + while (pFile->current[0] != ':') pFile->current++; + pFile->current += 2; + + begin = pFile->current; + + /* search for the end of expected text */ + + while (((pFile->current - pFile->start) + 2) <= pFile->length) { + + if ((pFile->current[0] == '\r') && (pFile->current[1] == '\n')) { + + len = pFile->current - begin; + + if ((len > 512) || (len < 1)) { + return FALSE; + } + + pEdid->name = nvalloc(len + 1); + + strncpy(pEdid->name, begin, len); + pEdid->name[len] = '\0'; + + return TRUE; + } + pFile->current++; + } + + return FALSE; + +} // readMonitorNameforTextFile() + +/* + * findFileName() - determine the filename to use for writing out the + * EDID + */ + +static char *findFileName(char *option) +{ + char *tmp; + struct passwd *pw; + + /* if the user gave an option, start by expanding '~' */ + + if (option) { + return tilde_expansion(option); + } + + /* if we can write to the current directory, then use that */ + + if (access(".", R_OK|W_OK|X_OK|F_OK) == 0) { + return nvstrcat("./", EDID_OUTPUT_FILE_NAME, NULL); + } + + /* + * otherwise, if we can get the user's home directory, and have + * access to it, then use it + */ + + tmp = getenv("HOME"); + + if (!tmp) { + pw = getpwuid(getuid()); + if (pw) tmp = pw->pw_dir; + } + + if (tmp && (access(tmp, R_OK|W_OK|X_OK|F_OK) == 0)) { + return nvstrcat(tmp, "/", EDID_OUTPUT_FILE_NAME, NULL); + } + + /* finally, just give them /tmp/edid.bin */ + + return nvstrcat("/tmp/", EDID_OUTPUT_FILE_NAME, NULL); + +} // findFileName() + + + +/* + * writeEdidFile() - write the EDID to file + */ + +static int writeEdidFile(EdidPtr pEdid, char *filename) +{ + int fd = -1, ret = FALSE; + char *dst = (void *) -1; + char *msg = "?"; + char *working_filename; + char scratch[64]; + int n; + + /* + * create a unique filename; if the given filename isn't already + * unique, append ".#" until it is unique. + * + * XXX there is a race between checking the existence of the file, + * here, and opening the file below + */ + + n = 0; + working_filename = tilde_expansion(filename); + + if (!working_filename) { + msg = "Memory allocation failure"; + goto done; + } + + while (access(working_filename, F_OK) == 0) { + snprintf(scratch, 64, "%d", n++); + nvfree(working_filename); + working_filename = nvstrcat(filename, ".", scratch, NULL); + } + + /* open the file */ + + fd = open(working_filename, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + + if (fd == -1) { + msg = "Unable to open file for writing"; + goto done; + } + + /* set the size of the file */ + + if (lseek(fd, pEdid->size - 1, SEEK_SET) == -1) { + msg = "Unable to set file size"; + goto done; + } + + if (write(fd, "", 1) != 1) { + msg = "Unable to write output file size"; + goto done; + } + + /* mmap the file */ + + if ((dst = mmap(0, pEdid->size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0)) == (void *) -1) { + msg = "Unable to map file for copying"; + goto done; + } + + /* copy the data into the file */ + + memcpy(dst, pEdid->bytes, pEdid->size); + + /* record success and fall through into done */ + + ret = TRUE; + + done: + + /* unmap the file */ + + if (dst != (void *) -1) { + if (munmap(dst, pEdid->size) != 0) { + msg = "Unable to unmap file"; + ret = FALSE; + } + } + + /* close the file */ + + if (fd != -1) { + if (close(fd) != 0) { + msg = "Unable to close file"; + ret = FALSE; + } + } + + /* report what happened */ + + if (ret) { + nv_info_msg(NULL, " Wrote EDID for \"%s\" to \"%s\" (%d bytes).", + pEdid->name, working_filename, pEdid->size); + } else { + nv_error_msg("Failed to write EDID for \"%s\" to \"%s\" (%s)", + pEdid->name, working_filename, msg); + } + + nvfree(working_filename); + + return ret; + +} /* writeEdidFile() */ + + + +/* + * freeEdid() - free the EDID data structure + */ + +static void freeEdid(EdidPtr pEdid) +{ + if (pEdid->bytes) nvfree(pEdid->bytes); + if (pEdid->name) nvfree(pEdid->name); + + nvfree(pEdid); + +} /* freeEdid() */ diff --git a/nvidia-xconfig-540.3.0/gen-manpage-opts.c b/nvidia-xconfig-540.3.0/gen-manpage-opts.c new file mode 100644 index 0000000..00d0b9f --- /dev/null +++ b/nvidia-xconfig-540.3.0/gen-manpage-opts.c @@ -0,0 +1,15 @@ +/* + * Prints the option help in a form that is suitable to include in the manpage. + */ +#include +#include +#include + +#include "gen-manpage-opts-helper.h" +#include "option_table.h" + +int main(void) +{ + gen_manpage_opts_helper(__options); + return 0; +} diff --git a/nvidia-xconfig-540.3.0/lscf.c b/nvidia-xconfig-540.3.0/lscf.c new file mode 100644 index 0000000..6302df0 --- /dev/null +++ b/nvidia-xconfig-540.3.0/lscf.c @@ -0,0 +1,416 @@ +#include +#include "nvidia-xconfig.h" +#if defined(NV_SUNOS) + +/* Interface to the Solaris Service Management Facility. + * This facility is responsible for running programs and services + * and store their configuration information (named properties) + * The configuration information for the X server is managed by + * this facility. The functions in this source file use the library + * libscf (Service Configuration Facility) to access and modify + * the properties for the X server, more specifically the default depth. + * On Solaris, changing the default depth in the xorg.conf file is not + * enough. The session manager overrides the xorg.conf default depth: + * it passes the option -defdepth to the X server with the value + * retrieved from the Service Management Facility. + * + * For more information refer to the manpages of fmf(5), libsfc(3LIB), + * and to the source code of svccfg(1M) available on cvs.opensolaris.org. + */ + + +#include +#include "msg.h" + +static int lscf_init_handle(scf_handle_t **scf_handle, + scf_scope_t **scf_scope); +static int lscf_select(scf_handle_t *scf_handle, + scf_scope_t *scf_scope, + const char *selection, + scf_service_t **current_svc); +static int lscf_setprop_int(scf_handle_t *scf_handle, + scf_scope_t *scf_scope, + scf_service_t *current_svc, + const char *group, + const char *name, int value); +static int lscf_getprop_int(scf_handle_t *scf_handle, + scf_scope_t *scf_scope, + scf_service_t *current_svc, + const char *group, + const char *name, int *value); + +/* UPDATE THE DEFAULT DEPTH PROPERTY IN SMF WITH THE LIBSCF FUNCTIONS */ +int update_scf_depth(int depth) +{ + static scf_handle_t *scf_handle = NULL; + static scf_scope_t *scf_scope = NULL; + scf_service_t *curren_svc = NULL; + int status = 1; + + // Initialization of the handles + lscf_init_handle(&scf_handle, &scf_scope); + if (scf_handle == NULL) { + status =0; + goto done; + } + + // Set the current selection + if(!lscf_select(scf_handle, scf_scope, "application/x11/x11-server", + ¤_svc)) { + status =0; + goto done; + } + + // Set the depth property of the current selection + if(!lscf_setprop_int(scf_handle, scf_scope, curren_svc, + "options", "default_depth", depth)) { + status =0; + goto done; + } + +done: + if(curren_svc) scf_service_destroy(curren_svc); + if(scf_scope) scf_scope_destroy(scf_scope); + if(scf_handle) { + scf_handle_unbind(scf_handle); + scf_handle_destroy(scf_handle); + } + if (!status) { + nv_error_msg("Unable to set X server default depth through " + "Solaris Service Management Facility"); + } + return status; +} + +/* READ THE DEFAULT DEPTH PROPERTY FROM SMF WITH THE LIBSCF FUNCTIONS */ +int read_scf_depth(int *depth) +{ + static scf_handle_t *scf_handle = NULL; + static scf_scope_t *scf_scope = NULL; + scf_service_t *curren_svc = NULL; + int status = 1; + + // Initialization of the handles + lscf_init_handle(&scf_handle, &scf_scope); + if (scf_handle == NULL) { + status =0; + goto done; + } + + // Set the current selection + if(!lscf_select(scf_handle, scf_scope, "application/x11/x11-server", + ¤_svc)) { + status =0; + goto done; + } + + // Get the depth property of the current selection + if(!lscf_getprop_int(scf_handle, scf_scope, curren_svc, + "options", "default_depth", depth)) { + status =0; + goto done; + } + +done: + if(curren_svc) scf_service_destroy(curren_svc); + if(scf_scope) scf_scope_destroy(scf_scope); + if(scf_handle) { + scf_handle_unbind(scf_handle); + scf_handle_destroy(scf_handle); + } + if (!status) { + nv_error_msg("Unable to get X server default depth from " + "Solaris Service Management Facility"); + } + return status; +} + + +/* INITIALIZATION OF THE HANDLES */ +static int lscf_init_handle(scf_handle_t **scf_handle, + scf_scope_t **scf_scope) +{ + scf_handle_t *handle = NULL; + scf_scope_t *scope = NULL;; + + *scf_handle = NULL; + *scf_scope = NULL; + + // Create a new Service Configuration Facility + // handle, needed for the communication with the + // configuration repository. + handle = scf_handle_create(SCF_VERSION); + if (handle == NULL) { + return 0; + } + + // Bind the handle to the running svc.config daemon + if (scf_handle_bind(handle) != 0) { + scf_handle_destroy(handle); + return 0; + } + + + // Allocate a new scope. A scope is a top level of the + // SCF repository tree. + scope = scf_scope_create(handle); + if (scope == NULL) { + scf_handle_unbind(handle); + scf_handle_destroy(handle); + return 0; + } + + // Set the scope to the root of the local SCF repository tree. + if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) !=0) { + scf_scope_destroy(scope); + scf_handle_unbind(handle); + scf_handle_destroy(handle); + return 0; + } + + *scf_handle = handle; + *scf_scope = scope; + + return 1; +} + + +/* EQUIVALENT TO THE SVCCFG SELECT COMMAND */ +static int lscf_select(scf_handle_t *scf_handle, + scf_scope_t *scf_scope, + const char *selection, + scf_service_t **current_svc) +{ + scf_service_t *svc; + + // Services are children of a scope, and + // contain configuration information for + // the service. + svc = scf_service_create(scf_handle); + if (svc == NULL) { + return 0; + } + + // Set the service 'svc' to the service specified + // by 'selection', in the scope 'scf_scope'. + if (scf_scope_get_service(scf_scope, selection, svc) == SCF_SUCCESS) { + *current_svc = svc; + return 1; + } + + scf_service_destroy(svc); + return 0; +} + +/* EQUIVALENT TO THE SVCCFG SETPROP COMMAND FOR AN INTEGER TYPED VALUE */ +static int lscf_setprop_int(scf_handle_t *scf_handle, + scf_scope_t *scf_scope, + scf_service_t *current_svc, + const char *group, + const char *name, int value) +{ + scf_transaction_entry_t *entry=NULL; + scf_propertygroup_t *pg = NULL; + scf_property_t *prop = NULL; + scf_transaction_t *transax = NULL; + scf_value_t *v = NULL; + int status = 1; + + // Allocate a new transaction entry handle + entry = scf_entry_create(scf_handle); + if (entry == NULL) { + status=0; + goto done; + } + + // Allocate a property group. + pg = scf_pg_create(scf_handle); + if (pg == NULL) { + status=0; + goto done; + } + + // Allocate a property. A property is a named set + // of values. + prop = scf_property_create(scf_handle); + if (prop == NULL) { + status=0; + goto done; + } + + // Allocate a transaction, used to change + // property groups. + transax = scf_transaction_create(scf_handle); + if (transax == NULL) { + status=0; + goto done; + } + + // Allocate a value. + v = scf_value_create(scf_handle); + if (v == NULL) { + status=0; + goto done; + } + + // Set the the property group 'pg' to the + // groups specified by 'group' in the service + // specified by 'current_svc' + if (scf_service_get_pg(current_svc, group, pg) != SCF_SUCCESS) { + status=0; + goto done; + } + + // Update the property group. + if (scf_pg_update(pg) == -1) { + status=0; + goto done; + } + + // Set up the transaction to modify the property group. + if (scf_transaction_start(transax, pg) != SCF_SUCCESS) { + status=0; + goto done; + } + + // Set the property 'prop' to the property + // specified ny 'name' in the property group 'pg' + if (scf_pg_get_property(pg, name, prop) == SCF_SUCCESS) { + // Found + // It should be already of integer type. + // To be secure, reset the property type to integer. + if (scf_transaction_property_change_type(transax, entry, + name, SCF_TYPE_INTEGER) == -1) { + status=0; + goto done; + } + } else { + // Not found + // Add a new property to the property group. + if (scf_transaction_property_new(transax, entry, + name, SCF_TYPE_INTEGER) + == -1) { + status=0; + goto done; + } + } + + // Set the integer value + scf_value_set_integer(v, value); + + // Set up the value to the property. + if (scf_entry_add_value(entry, v) != SCF_SUCCESS) { + status=0; + goto done; + } + + // Commit the transaction + if (scf_transaction_commit(transax) < 0) { + status=0; + } + +done: + if (entry) scf_entry_destroy(entry); + if (pg) scf_pg_destroy(pg); + if (prop) scf_property_destroy(prop); + if (transax) scf_transaction_destroy(transax); + if (v) scf_value_destroy(v); + return status; +} + +/* EQUIVALENT TO THE SVCCFG SETPROP COMMAND FOR AN INTEGER TYPED VALUE */ +static int lscf_getprop_int(scf_handle_t *scf_handle, + scf_scope_t *scf_scope, + scf_service_t *current_svc, + const char *group, + const char *name, int *value) +{ + scf_transaction_entry_t *entry=NULL; + scf_propertygroup_t *pg = NULL; + scf_property_t *prop = NULL; + scf_value_t *v = NULL; + int status = 1; + int64_t t; + + // Allocate a new transaction entry handle + entry = scf_entry_create(scf_handle); + if (entry == NULL) { + status=0; + goto done; + } + + // Allocate a property group. + pg = scf_pg_create(scf_handle); + if (pg == NULL) { + status=0; + goto done; + } + + // Allocate a property. A property is a named set + // of values. + prop = scf_property_create(scf_handle); + if (prop == NULL) { + status=0; + goto done; + } + + // Set the the property group 'pg' to the + // groups specified by 'group' in the service + // specified by 'current_svc' + if (scf_service_get_pg(current_svc, group, pg) != SCF_SUCCESS) { + status=0; + goto done; + } + + // Update the property group. + if (scf_pg_update(pg) == -1) { + status=0; + goto done; + } + + // Set the property 'prop' to the property + // specified ny 'name' in the property group 'pg' + if (scf_pg_get_property(pg, name, prop) != SCF_SUCCESS) { + status=0; + goto done; + } + + // Allocate a value. + v = scf_value_create(scf_handle); + if (v == NULL) { + status=0; + goto done; + } + + // Get the value + if (scf_property_get_value(prop, v) != SCF_SUCCESS) { + status=0; + goto done; + } + + // Get the integer value + if (scf_value_get_integer(v, &t) != SCF_SUCCESS) { + status=0; + goto done; + } + + *value = (int)t; + +done: + if (entry) scf_entry_destroy(entry); + if (pg) scf_pg_destroy(pg); + if (prop) scf_property_destroy(prop); + if (v) scf_value_destroy(v); + return status; +} +#else // NOT SOLARIS +int update_scf_depth(int depth) +{ + return 1; +} + +int read_scf_depth(int *depth) +{ + return 0; +} +#endif diff --git a/nvidia-xconfig-540.3.0/make_usable.c b/nvidia-xconfig-540.3.0/make_usable.c new file mode 100644 index 0000000..27bd307 --- /dev/null +++ b/nvidia-xconfig-540.3.0/make_usable.c @@ -0,0 +1,437 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2005 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * make_usable.c + */ + +#include +#include +#include +#include + +#include "nvidia-xconfig.h" +#include "xf86Parser.h" +#include "configProcs.h" +#include "msg.h" +#include "nvpci-utils.h" + + +static void ensure_module_loaded(XConfigPtr config, char *name); +static int update_device(Options *op, XConfigPtr config, XConfigDevicePtr device); +static void update_depth(Options *op, XConfigScreenPtr screen); +static void update_display(Options *op, XConfigScreenPtr screen); + +/* + * ensure_module_loaded() - make sure the given module is present + */ + +static void ensure_module_loaded(XConfigPtr config, char *name) { + XConfigLoadPtr load; + int found = FALSE; + + for (load = config->modules->loads; load && !found; load = load->next) { + if (xconfigNameCompare(name, load->name) == 0) found = TRUE; + } + + if (!found) { + xconfigAddNewLoadDirective(&config->modules->loads, + name, XCONFIG_LOAD_MODULE, + NULL, FALSE); + } +} /* ensure_module_loaded */ + +/* + * update_modules() - make sure the glx module is present, and remove + * the GLcore and dri modules if they are present. + */ + +int update_modules(XConfigPtr config) +{ + XConfigLoadPtr load, next; + + /* + * Return early if the original X configuration file lacked a + * "Module" section, and rely on the server's builtin list + * of modules to load, instead. We can safely do this if the + * X server is an X.Org server or XFree86 release >= 4.4.0. On + * installations with older XFree86 servers, the vendor's X + * configuration utility should have added a "Module" section + * we can extend, if necessary. + */ + if (config->modules == NULL) + return FALSE; + + /* make sure all our required modules are loaded */ + ensure_module_loaded(config, "glx"); +#if defined(NV_SUNOS) + ensure_module_loaded(config, "xtsol"); +#endif // defined(NV_SUNOS) + + /* make sure GLcore and dri are not loaded */ + + load = config->modules->loads; + while (load) { + next = load->next; + if (xconfigNameCompare("GLcore", load->name) == 0) { + xconfigRemoveLoadDirective(&config->modules->loads, load); + } else if (xconfigNameCompare("dri", load->name) == 0) { + xconfigRemoveLoadDirective(&config->modules->loads, load); + } + load = next; + } + + return TRUE; + +} /* update_modules() */ + + + +/* + * update_screen() - apply any requested updates to the given screen + */ + +int update_screen(Options *op, XConfigPtr config, XConfigScreenPtr screen) +{ + /* migrate any options from device to screen to avoid conflicts */ + screen->options = xconfigOptionListMerge(screen->options, + screen->device->options); + screen->device->options = NULL; + + update_display(op, screen); + update_depth(op, screen); + update_device(op, config, screen->device); + update_options(op, screen); + + return TRUE; + +} /* update_screen() */ + + + +/* + * get_layout() - get the right layout from the config that we should + * edit + */ + +XConfigLayoutPtr get_layout(Options *op, XConfigPtr config) +{ + XConfigLayoutPtr layout; + + /* select a screenLayout to use */ + + if (op->layout) { + + /* if a layout was specified on the commandline, use that */ + + layout = xconfigFindLayout(op->layout, config->layouts); + if (!layout) { + nv_error_msg("Unable to find layout \"%s\".\n", op->layout); + return NULL; + } + } else { + + /* otherwise, use the first layout in the config file */ + + if (!config->layouts) { + nv_error_msg("unable to select ScreenLayout to use.\n"); + return NULL; + } + + layout = config->layouts; + } + + return layout; + +} /* get_layout() */ + + + +/* + * update_extensions() - apply any requested updates to the Extensions + * section; currently, this only applies to the Composite option. + */ + +int update_extensions(Options *op, XConfigPtr config) +{ + char *value; + + /* validate the composite option against any other options specified */ + + validate_composite(op, config); + + if (GET_BOOL_OPTION(op->boolean_options, COMPOSITE_BOOL_OPTION)) { + + /* if we don't already have the Extensions section, create it now */ + + if (!config->extensions) { + config->extensions = calloc(1, sizeof(XConfigExtensionsRec)); + } + + /* remove any existing composite extension option */ + xconfigRemoveNamedOption(&(config->extensions->options), + op->gop.compositeExtensionName, + NULL); + + + /* determine the value to set for the Composite option */ + + value = GET_BOOL_OPTION(op->boolean_option_values, + COMPOSITE_BOOL_OPTION) ? + "Enable" : "Disable"; + + /* add the option */ + xconfigAddNewOption(&config->extensions->options, + op->gop.compositeExtensionName, + value); + } + + return TRUE; + +} /* update_extensions() */ + + +/* + * update_server_flags() - update the server flags section with any + * server flag options; the only option so far is "HandleSpecialKeys" + */ + +int update_server_flags(Options *op, XConfigPtr config) +{ + if (!op->handle_special_keys) return TRUE; + + if (!config->flags) { + config->flags = nvalloc(sizeof(XConfigFlagsRec)); + if ( !config->flags ) { + return FALSE; + } + } + + if (config->flags->options) { + xconfigRemoveNamedOption(&(config->flags->options), + "HandleSpecialKeys", NULL); + } + + if (op->handle_special_keys != NV_DISABLE_STRING_OPTION) { + xconfigAddNewOption(&config->flags->options, "HandleSpecialKeys", + op->handle_special_keys); + } + + return TRUE; + +} /* update_server_flags() */ + + + + +static int count_non_nv_gpus(void) +{ + struct pci_device_iterator *iter; + struct pci_device *dev; + int count = 0; + + if (pci_system_init()) { + return -1; + } + + iter = nvpci_find_gpu_by_vendor(PCI_MATCH_ANY); + + for (dev = pci_device_next(iter); dev; dev = pci_device_next(iter)) { + if (dev->vendor_id != NV_PCI_VENDOR_ID) { + count++; + } + } + + pci_system_cleanup(); + + return count; +} + + + + +/* + * update_device() - update the device; there is a lot of information + * in the device that is not relevant to the NVIDIA X driver. In + * fact, some options, like "Chipset" can actually prevent XFree86 + * from using the NVIDIA driver. The simplest solution is to zero out + * the device, and only retain the few fields that are meaningful for + * the NVIDIA X driver. + */ + +static int update_device(Options *op, XConfigPtr config, XConfigDevicePtr device) +{ + char *identifier, *vendor, *comment, *board, *busid, *driver; + int screen; + size_t index_id; + XConfigDevicePtr next; + XConfigOptionPtr options; + + next = device->next; + options = device->options; + identifier = device->identifier; + vendor = device->vendor; + comment = device->comment; + screen = device->screen; + board = device->board; + busid = device->busid; + driver = device->driver; + index_id = device->index_id; + + memset(device, 0, sizeof(XConfigDeviceRec)); + + device->next = next; + device->options = options; + device->identifier = identifier; + device->vendor = vendor; + device->comment = comment; + device->screen = screen; + device->board = board; + device->index_id = index_id; + + /* + * Considering five conditions, in order, while populating busid field + * 1. If the field is required for the configuration chosen and not passed in + * 2. If the user specified "--no-busid", obey that + * 3. If we want to write busid with option --busid + * 4. If we want to preserve existing bus id + * 5. If there are multiple screens + * 6. If the system has any non-NVIDIA GPUs + */ + + if (GET_BOOL_OPTION(op->boolean_option_values, ENABLE_PRIME_OPTION) && + op->busid == NULL) { + device->busid = nv_format_busid(op, device->index_id); + if (device->busid == NULL) { + return FALSE; + } + } else if (op->busid == NV_DISABLE_STRING_OPTION) { + device->busid = NULL; + } else if (op->busid) { + device->busid = op->busid; + } else if (GET_BOOL_OPTION(op->boolean_options, + PRESERVE_BUSID_BOOL_OPTION)) { + if (GET_BOOL_OPTION(op->boolean_option_values, + PRESERVE_BUSID_BOOL_OPTION)) { + device->busid = busid; + } else { + device->busid = NULL; + } + } else if (config->screens->next) { + /* enable_separate_x_screens() already generated a busid string */ + device->busid = busid; + } else if (count_non_nv_gpus() > 0) { + device->busid = nv_format_busid(op, device->index_id); + if (device->busid == NULL) { + return FALSE; + } + } + + device->chipid = -1; + device->chiprev = -1; + device->irq = -1; + + if (op->preserve_driver) { + device->driver = driver; + } else { + device->driver = "nvidia"; + } + + return TRUE; + +} /* update_device() */ + + + +/* + * update_depth() - make sure there is a display section with the + * default depth, and possibly update the default depth + */ + +static void update_depth(Options *op, XConfigScreenPtr screen) +{ + XConfigDisplayPtr display; + int found; + + /* update the depth */ + if ((op->depth == 8) || (op->depth == 15) || + (op->depth == 16) || (op->depth == 24) || + (op->depth == 30)) { + screen->defaultdepth = op->depth; + } else { + /* read the default depth to SVC and set it as the default depth */ + int scf_depth; + + if (read_scf_depth(&scf_depth) && scf_depth != screen->defaultdepth) { + nv_warning_msg("The default depth of %d read from " + "the Solaris Management Facility is set as the " + "default depth for screen \"%s\"", scf_depth, + screen->identifier); + screen->defaultdepth = scf_depth; + } + } + + /* + * if there is no display at the default depth, force the first + * display section to that depth + */ + + found = FALSE; + + for (display = screen->displays; display; display = display->next) { + if (display->depth == screen->defaultdepth) { + found = TRUE; + break; + } + } + + if (!found) { + screen->displays->depth = screen->defaultdepth; + } + +} /* update_depth() */ + + + +/* + * update_display() - if there are no display subsections, create one + */ + +static void update_display(Options *op, XConfigScreenPtr screen) +{ + + if (!screen->displays) { + XConfigDisplayPtr display; + XConfigModePtr mode = NULL; + + xconfigAddMode(&mode, "nvidia-auto-select"); + + display = nvalloc(sizeof(XConfigDisplayRec)); + display->depth = screen->defaultdepth; + display->modes = mode; + display->frameX0 = -1; + display->frameY0 = -1; + display->black.red = -1; + display->white.red = -1; + + screen->displays = display; + } + +} /* update_display() */ + + diff --git a/nvidia-xconfig-540.3.0/multiple_screens.c b/nvidia-xconfig-540.3.0/multiple_screens.c new file mode 100644 index 0000000..6f0fded --- /dev/null +++ b/nvidia-xconfig-540.3.0/multiple_screens.c @@ -0,0 +1,1091 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2005 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * multiple_screens.c + */ + +#include "nvidia-xconfig.h" +#include "xf86Parser.h" +#include "msg.h" + +#include +#include +#include + + +static int enable_separate_x_screens(Options *op, XConfigPtr config, + XConfigLayoutPtr layout); +static int disable_separate_x_screens(Options *op, XConfigPtr config, + XConfigLayoutPtr layout); + +static int set_xinerama(int xinerama_enabled, XConfigLayoutPtr layout); + +static XConfigDisplayPtr clone_display_list(XConfigDisplayPtr display0); +static XConfigDevicePtr clone_device(XConfigDevicePtr device0, int idx); +static XConfigScreenPtr clone_screen(XConfigScreenPtr screen0, int idx); + +static void create_adjacencies(Options *op, XConfigPtr config, + XConfigLayoutPtr layout); + +static int enable_all_gpus(Options *op, XConfigPtr config, + XConfigLayoutPtr layout); + +static void free_unused_devices(Options *op, XConfigPtr config); +static void free_unused_monitors(Options *op, XConfigPtr config); + +static int only_one_screen(Options *op, XConfigPtr config, + XConfigLayoutPtr layout); + +/* + * get_screens_to_clone() - try to detect automatically how many heads has each + * device in order to use that number to create more than two separate X + * screens. If the user specifies the option --num-x-screens , that + * value is used. If neither the user specifies the quantity or the number of + * heads can be detected automatically, it uses 2 heads (the standard + * behavior). This function returns an array of size nscreens with the number + * of screens to clone per screen candidate. The caller is responsible of + * freeing the memory of that array. + */ +static int* get_screens_to_clone(Options *op, + const XConfigScreenPtr *screen_candidates, + int nscreens) +{ + DevicesPtr pDevices; + int *screens_to_clone, *supported_screens; + int i, j, devs_found; + + screens_to_clone = nvalloc(nscreens * sizeof(int)); + supported_screens = nvalloc(nscreens * sizeof(int)); + + /* Detect the number of supported screens per screen candidate */ + devs_found = FALSE; + pDevices = find_devices(op); + if (pDevices) { + for (i = 0; i < nscreens; i++) { + int bus, slot, scratch; + + if (!screen_candidates[i]) { + continue; + } + + /* parse the bus id for this candidate screen */ + if (!xconfigParsePciBusString(screen_candidates[i]->device->busid, + &bus, &slot, &scratch)) { + continue; + } + + for (j = 0; j < pDevices->nDevices; j++) { + if ((pDevices->devices[j].dev.bus == bus) && + (pDevices->devices[j].dev.slot == slot)) { + + if (pDevices->devices[j].crtcs > 0) { + supported_screens[i] = pDevices->devices[j].crtcs; + } + break; + } + } + } + free_devices(pDevices); + devs_found = TRUE; + } + + /* If user has defined a number of screens per GPU, use that value */ + if (op->num_x_screens > 0) { + for (i = 0; i < nscreens; i++) { + if (!screen_candidates[i]) { + continue; + } + + /* Print error when user specifies more X screens than supported */ + if (devs_found && op->num_x_screens > supported_screens[i]) { + nv_warning_msg("Number of X screens specified is higher than the " + "supported quantity (%d)", supported_screens[i]); + } + + screens_to_clone[i] = op->num_x_screens; + } + + goto done; + } + + for (i = 0; i < nscreens; i++) { + if (screen_candidates[i]) { + if (devs_found) { + /* If devices found, use the supported screens number */ + screens_to_clone[i] = supported_screens[i]; + } + else { + /* Default behavior (2 heads per GPU) */ + screens_to_clone[i] = 2; + } + } + } + +done: + nvfree(supported_screens); + return screens_to_clone; +} + +/* + * clean_screen_list() - Used by enable_separate_x_screens and + * disable_separate_x_screens. Given the array screen_list and the config + * pointer, this function will leave only one screen per different busid in both + * screen_list array and config->screens list (i.e all the resulting screens in + * screen_list and config->screens will have an unique busid). + */ +static void clean_screen_list(XConfigScreenPtr *screen_list, + XConfigPtr config, + int nscreens) +{ + int i, j; + int *bus, *slot, scratch; + + /* trim out duplicates and get the bus ids*/ + + bus = nvalloc(sizeof(int) * nscreens); + slot = nvalloc(sizeof(int) * nscreens); + + for (i = 0; i < nscreens; i++) { + bus[i] = -1; + } + + for (i = 0; i < nscreens; i++) { + if (!screen_list[i] || (bus[i] == -1 && + !xconfigParsePciBusString(screen_list[i]->device->busid, + &bus[i], &slot[i], &scratch))) { + continue; + } + + for (j = i+1; j < nscreens; j++) { + if (!screen_list[j] || (bus[j] == -1 && + !xconfigParsePciBusString(screen_list[j]->device->busid, + &bus[j], &slot[j], &scratch))) { + continue; + } + + if ((bus[i] == bus[j]) && (slot[i] == slot[j])) { + screen_list[j] = NULL; + } + } + } + + /* + * for every screen in the screen list, scan through all + * screens; if any screen, other than *this* screen has the same + * busid, remove it + */ + + for (i = 0; i < nscreens; i++) { + XConfigScreenPtr screen, prev; + int bus0, slot0; + + if (!screen_list[i]) { + continue; + } + + screen = config->screens; + prev = NULL; + + while (screen) { + if (screen_list[i] == screen) { + goto next_screen; + } + if (!screen->device) { + goto next_screen; + } + if (!screen->device->busid) { + goto next_screen; + } + if (!xconfigParsePciBusString(screen->device->busid, + &bus0, &slot0, &scratch)) { + goto next_screen; + } + + if ((bus[i] == bus0) && (slot[i] == slot0)) { + XConfigScreenPtr next; + + if (prev) { + prev->next = screen->next; + } + else { + config->screens = screen->next; + } + + next = screen->next; + screen->next = NULL; + xconfigFreeScreenList(&screen); + screen = next; + } + else { + + next_screen: + + prev = screen; + screen = screen->next; + } + } + + screen_list[i]->device->screen = -1; + } +} + +/* + * apply_multi_screen_options() - there are 4 options that can affect + * multiple X screens: + * + * - add X screens for all GPUS in the system + * - separate X screens on one GPU (turned on or off) + * - only one X screen + * - Xinerama + * + * apply these options in that order + */ + +int apply_multi_screen_options(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + if (op->enable_all_gpus) { + if (!enable_all_gpus(op, config, layout)) return FALSE; + } + + + if (GET_BOOL_OPTION(op->boolean_options, + SEPARATE_X_SCREENS_BOOL_OPTION)) { + if (GET_BOOL_OPTION(op->boolean_option_values, + SEPARATE_X_SCREENS_BOOL_OPTION)) { + if (!enable_separate_x_screens(op, config, layout)) return FALSE; + } else { + if (!disable_separate_x_screens(op, config, layout)) return FALSE; + } + } + + if (GET_BOOL_OPTION(op->boolean_options, + XINERAMA_BOOL_OPTION)) { + if (!set_xinerama(GET_BOOL_OPTION(op->boolean_option_values, + XINERAMA_BOOL_OPTION), + layout)) return FALSE; + } + + if (op->only_one_screen) { + if (!only_one_screen(op, config, layout)) return FALSE; + } + + return TRUE; + +} /* apply_multi_screen_options() */ + + + +/* + * find_devices() - dlopen the nvidia-cfg library and query the + * available information about the GPUs in the system. + */ + +DevicesPtr find_devices(Options *op) +{ + DevicesPtr pDevices = NULL; + DisplayDevicePtr pDisplayDevice; + int i, j, n, count = 0; + int swappedIndex; + unsigned int mask, bit; + DeviceRec tmpDevice; + NvCfgPciDevice *devs = NULL; + NvCfgBool is_primary_device; + NvCfgBool ret; + char *lib_path; + void *lib_handle; + + NvCfgBool (*__getDevices)(int *n, NvCfgDevice **devs); + NvCfgBool (*__openDevice)(int bus, int slot, NvCfgDeviceHandle *handle); + NvCfgBool (*__getPciDevices)(int *n, NvCfgPciDevice **devs); + NvCfgBool (*__openPciDevice)(int domain, int bus, int slot, int function, + NvCfgDeviceHandle *handle); + NvCfgBool (*__getNumCRTCs)(NvCfgDeviceHandle handle, int *crtcs); + NvCfgBool (*__getProductName)(NvCfgDeviceHandle handle, char **name); + NvCfgBool (*__getDisplayDevices)(NvCfgDeviceHandle handle, + unsigned int *display_device_mask); + NvCfgBool (*__getEDID)(NvCfgDeviceHandle handle, + unsigned int display_device, + NvCfgDisplayDeviceInformation *info); + NvCfgBool (*__isPrimaryDevice)(NvCfgDeviceHandle handle, + NvCfgBool *is_primary_device); + NvCfgBool (*__closeDevice)(NvCfgDeviceHandle handle); + NvCfgBool (*__getDeviceUUID)(NvCfgDeviceHandle handle, char **uuid); + + /* dlopen() the nvidia-cfg library */ + +#define __LIB_NAME "libnvidia-cfg.so.1" + + if (op->nvidia_cfg_path) { + lib_path = nvstrcat(op->nvidia_cfg_path, "/", __LIB_NAME, NULL); + } else { + lib_path = strdup(__LIB_NAME); + } + + lib_handle = dlopen(lib_path, RTLD_NOW); + + nvfree(lib_path); + + if (!lib_handle) { + nv_warning_msg("error opening %s: %s.", __LIB_NAME, dlerror()); + return NULL; + } + +#define __GET_FUNC(proc, name) \ + (proc) = dlsym(lib_handle, (name)); \ + if (!(proc)) { \ + nv_warning_msg("error retrieving symbol %s from %s: %s", \ + (name), __LIB_NAME, dlerror()); \ + dlclose(lib_handle); \ + return NULL; \ + } + + /* required functions */ + __GET_FUNC(__getDevices, "nvCfgGetDevices"); + __GET_FUNC(__openDevice, "nvCfgOpenDevice"); + __GET_FUNC(__getPciDevices, "nvCfgGetPciDevices"); + __GET_FUNC(__openPciDevice, "nvCfgOpenPciDevice"); + __GET_FUNC(__getNumCRTCs, "nvCfgGetNumCRTCs"); + __GET_FUNC(__getProductName, "nvCfgGetProductName"); + __GET_FUNC(__getDisplayDevices, "nvCfgGetDisplayDevices"); + __GET_FUNC(__getEDID, "nvCfgGetEDID"); + __GET_FUNC(__closeDevice, "nvCfgCloseDevice"); + __GET_FUNC(__getDeviceUUID, "nvCfgGetDeviceUUID"); + __GET_FUNC(__isPrimaryDevice,"nvCfgIsPrimaryDevice"); + + if (__getPciDevices(&count, &devs) != NVCFG_TRUE) { + return NULL; + } + + if (count == 0) return NULL; + + pDevices = nvalloc(sizeof(DevicesRec)); + + pDevices->devices = nvalloc(sizeof(DeviceRec) * count); + + pDevices->nDevices = count; + + for (i = 0; i < count; i++) { + + pDevices->devices[i].dev = devs[i]; + + if (__openPciDevice(devs[i].domain, devs[i].bus, devs[i].slot, 0, + &(pDevices->devices[i].handle)) != NVCFG_TRUE) { + goto fail; + } + + if (__getNumCRTCs(pDevices->devices[i].handle, + &pDevices->devices[i].crtcs) != NVCFG_TRUE) { + goto fail; + } + + if (__getProductName(pDevices->devices[i].handle, + &pDevices->devices[i].name) != NVCFG_TRUE) { + /* This call may fail with little impact to the Device section */ + pDevices->devices[i].name = NULL; + } + + if (__getDeviceUUID(pDevices->devices[i].handle, + &pDevices->devices[i].uuid) != NVCFG_TRUE) { + goto fail; + } + if (__getDisplayDevices(pDevices->devices[i].handle, &mask) != + NVCFG_TRUE) { + goto fail; + } + + pDevices->devices[i].displayDeviceMask = mask; + + /* count the number of display devices */ + + for (n = j = 0; j < 32; j++) { + if (mask & (1 << j)) n++; + } + + pDevices->devices[i].nDisplayDevices = n; + + if (n) { + + /* allocate the info array of the right size */ + + pDevices->devices[i].displayDevices = + nvalloc(sizeof(DisplayDeviceRec) * n); + + /* fill in the info array */ + + for (n = j = 0; j < 32; j++) { + bit = 1 << j; + if (!(bit & mask)) continue; + + pDisplayDevice = &pDevices->devices[i].displayDevices[n]; + pDisplayDevice->mask = bit; + + if (__getEDID(pDevices->devices[i].handle, bit, + &pDisplayDevice->info) != NVCFG_TRUE) { + pDisplayDevice->info_valid = FALSE; + } else { + pDisplayDevice->info_valid = TRUE; + } + n++; + } + } else { + pDevices->devices[i].displayDevices = NULL; + } + + /* Use this index instead of i to close device after a possible swap */ + swappedIndex = i; + + if ((i != 0) && + (__isPrimaryDevice(pDevices->devices[i].handle, + &is_primary_device) == NVCFG_TRUE) && + (is_primary_device == NVCFG_TRUE)) { + memcpy(&tmpDevice, &pDevices->devices[0], sizeof(DeviceRec)); + memcpy(&pDevices->devices[0], &pDevices->devices[i], sizeof(DeviceRec)); + memcpy(&pDevices->devices[i], &tmpDevice, sizeof(DeviceRec)); + swappedIndex = 0; + } + + ret = __closeDevice(pDevices->devices[swappedIndex].handle); + pDevices->devices[swappedIndex].handle = NULL; + + if (ret != NVCFG_TRUE) { + goto fail; + } + } + + goto done; + + fail: + + nv_warning_msg("Unable to use the nvidia-cfg library to query NVIDIA " + "hardware."); + + for (i = 0; i < pDevices->nDevices; i++) { + /* close the opened device */ + if (pDevices->devices[i].handle) { + __closeDevice(pDevices->devices[i].handle); + } + } + + free_devices(pDevices); + pDevices = NULL; + + /* fall through */ + + done: + + if (devs) free(devs); + + return pDevices; + +} /* find_devices() */ + + + +/* + * free_devices() + */ + +void free_devices(DevicesPtr pDevices) +{ + int i; + + if (!pDevices) return; + + for (i = 0; i < pDevices->nDevices; i++) { + if (pDevices->devices[i].displayDevices) { + nvfree(pDevices->devices[i].displayDevices); + } + } + + if (pDevices->devices) { + nvfree(pDevices->devices); + } + + nvfree(pDevices); + +} /* free_devices() */ + + + +/* + * set_xinerama() - This makes sure there is a ServerLayout + * section and sets the "Xinerama" option + */ + +static int set_xinerama(int xinerama_enabled, XConfigLayoutPtr layout) +{ + xconfigAddNewOption(&(layout->options), + "Xinerama", + (xinerama_enabled ? "1" : "0")); + + return TRUE; + +} /* set_xinerama() */ + + + +/* + * enable_separate_x_screens() - this effectively clones each screen + * that is on a unique GPU. + * + * Algorithm: + * + * step 1: build a list of screens to be cloned + * + * step 2: assign a busID to every screen that is in the list (if + * BusIDs are not already assigned) + * + * step 3: clean the candidate list + * + * step 4: get the number of clones per screen candidate + * + * step 4: clone each eligible screen + * + * step 5: update adjacency list (just wipe the list and restart) + */ + +static int enable_separate_x_screens(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + XConfigScreenPtr screen, *screenlist = NULL; + XConfigAdjacencyPtr adj; + int* screens_to_clone = NULL; + + int i, nscreens = 0; + int have_busids; + + /* step 1: build the list of screens that are candidate to be cloned */ + + if (op->screen) { + screen = xconfigFindScreen(op->screen, config->screens); + if (!screen) { + nv_error_msg("Unable to find screen '%s'.", op->screen); + return FALSE; + } + + screenlist = nvalloc(sizeof(XConfigScreenPtr)); + screenlist[0] = screen; + nscreens = 1; + + } else { + for (adj = layout->adjacencies; adj; adj = adj->next) { + nscreens++; + screenlist = realloc(screenlist, + sizeof(XConfigScreenPtr) * nscreens); + + screenlist[nscreens-1] = adj->screen; + } + } + + if (!nscreens) return FALSE; + + /* step 2: do all screens in the list have a bus ID? */ + + have_busids = TRUE; + + for (i = 0; i < nscreens; i++) { + if (screenlist[i] && + screenlist[i]->device && + screenlist[i]->device->busid) { + // this screen has a busid + } else { + have_busids = FALSE; + break; + } + } + + /* + * if not everyone has a bus id, then let's assign bus ids to all + * the screens; XXX what if _some_ already have busids? Too bad, + * we're going to reassign all of them. + */ + + if (!have_busids) { + DevicesPtr pDevices; + + pDevices = find_devices(op); + if (!pDevices) { + nv_error_msg("Unable to determine number or location of " + "GPUs in system; cannot " + "honor '--separate-x-screens' option."); + return FALSE; + } + + for (i = 0; i < nscreens; i++) { + if (i >= pDevices->nDevices) { + /* + * we have more screens than GPUs, this screen is no + * longer a candidate + */ + screenlist[i] = NULL; + continue; + } + + screenlist[i]->device->busid = nv_format_busid(op, i); + + screenlist[i]->device->board = nvstrdup(pDevices->devices[i].name); + } + + free_devices(pDevices); + } + + /* step 3 */ + clean_screen_list(screenlist, config, nscreens); + + /* step 4 */ + screens_to_clone = get_screens_to_clone(op, screenlist, nscreens); + + /* step 5: clone each eligible screen */ + + for (i = 0; i < nscreens; i++) { + if (!screenlist[i]) continue; + + while (--screens_to_clone[i] > 0) { + clone_screen(screenlist[i], screens_to_clone[i]); + } + } + + nvfree(screens_to_clone); + + /* step 6: wipe the existing adjacencies and recreate them */ + + xconfigFreeAdjacencyList(&layout->adjacencies); + + create_adjacencies(op, config, layout); + + /* free unused device and monitor sections */ + + free_unused_devices(op, config); + free_unused_monitors(op, config); + + /* free stuff */ + + free(screenlist); + + return TRUE; + +} /* enable_separate_x_screens() */ + + +/* + * disable_separate_x_screens() - remove multiple screens that are + * configured for the same GPU. + * + * Algorithm: + * + * step 1: find which screens need to be "de-cloned" (either + * op->screen or all screens in the layout) + * + * step 2: narrow that list down to screens that have a busid + * specified + * + * step 3: clean the candidate list + * + * step 4: recompute the adjacency list + */ + +static int disable_separate_x_screens(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + XConfigScreenPtr screen, *screenlist = NULL; + XConfigAdjacencyPtr adj; + + int i, nscreens = 0; + + /* step 1: build the list of screens that are candidate to be de-cloned */ + + if (op->screen) { + screen = xconfigFindScreen(op->screen, config->screens); + if (!screen) { + nv_error_msg("Unable to find screen '%s'.", op->screen); + return FALSE; + } + + screenlist = nvalloc(sizeof(XConfigScreenPtr)); + screenlist[0] = screen; + nscreens = 1; + + } else { + for (adj = layout->adjacencies; adj; adj = adj->next) { + nscreens++; + screenlist = realloc(screenlist, + sizeof(XConfigScreenPtr) * nscreens); + + screenlist[nscreens-1] = adj->screen; + } + } + + /* + * step 2: limit the list to screens that have a BusID; parse the busIDs + * while we're at it + */ + + for (i = 0; i < nscreens; i++) { + int bus, slot, scratch; + if (screenlist[i] && + screenlist[i]->device && + screenlist[i]->device->busid && + xconfigParsePciBusString(screenlist[i]->device->busid, + &bus, &slot, &scratch)) { + // this screen has a valid busid + } else { + screenlist[i] = NULL; + } + } + + /* step 3 */ + clean_screen_list(screenlist, config, nscreens); + + /* step 4: wipe the existing adjacencies and recreate them */ + + xconfigFreeAdjacencyList(&layout->adjacencies); + + create_adjacencies(op, config, layout); + + /* free unused device and monitor sections */ + + free_unused_devices(op, config); + free_unused_monitors(op, config); + + /* free stuff */ + + free(screenlist); + + return TRUE; + +} /* disable_separate_x_screens() */ + + +/* + * clone_display_list() - create a duplicate of the specified display + * subsection. + */ + +static XConfigDisplayPtr clone_display_list(XConfigDisplayPtr display0) +{ + XConfigDisplayPtr d = NULL, prev = NULL, head = NULL; + + while (display0) { + d = nvalloc(sizeof(XConfigDisplayRec)); + memcpy(d, display0, sizeof(XConfigDisplayRec)); + if (display0->visual) d->visual = nvstrdup(display0->visual); + if (display0->comment) d->comment = nvstrdup(display0->comment); + d->options = xconfigOptionListDup(display0->options); + d->next = NULL; + if (prev) prev->next = d; + if (!head) head = d; + prev = d; + display0 = display0->next; + } + + return head; + +} /* clone_display_list() */ + + + +/* + * clone_device() - duplicate the specified device section, updating + * the screen indices as approprate for multiple X screens on one GPU + */ + +static XConfigDevicePtr clone_device(XConfigDevicePtr device0, int idx) +{ + XConfigDevicePtr device; + + device = nvalloc(sizeof(XConfigDeviceRec)); + + device->identifier = nvasprintf("%s (%d)", device0->identifier, idx); + + if (device0->vendor) device->vendor = nvstrdup(device0->vendor); + if (device0->board) device->board = nvstrdup(device0->board); + if (device0->chipset) device->chipset = nvstrdup(device0->chipset); + if (device0->busid) device->busid = nvstrdup(device0->busid); + if (device0->card) device->card = nvstrdup(device0->card); + if (device0->driver) device->driver = nvstrdup(device0->driver); + if (device0->ramdac) device->ramdac = nvstrdup(device0->ramdac); + if (device0->comment) device->comment = nvstrdup(device0->comment); + + /* these are needed for multiple X screens on one GPU */ + + device->screen = idx; + device0->screen = 0; + + device->chipid = -1; + device->chiprev = -1; + device->irq = -1; + + device->options = xconfigOptionListDup(device0->options); + + /* insert the new device after the original device */ + + device->next = device0->next; + device0->next = device; + + return device; + +} /* clone_device() */ + + + +/* + * clone_screen() - duplicate the given screen, for use as the ith + * X screen on one GPU + */ + +static XConfigScreenPtr clone_screen(XConfigScreenPtr screen0, int idx) +{ + XConfigScreenPtr screen = nvalloc(sizeof(XConfigScreenRec)); + + screen->identifier = nvasprintf("%s (%d)", screen0->identifier, idx); + + screen->device = clone_device(screen0->device, idx); + screen->device_name = nvstrdup(screen->device->identifier); + + screen->monitor = screen0->monitor; + screen->monitor_name = nvstrdup(screen0->monitor_name); + + screen->defaultdepth = screen0->defaultdepth; + + screen->displays = clone_display_list(screen0->displays); + + screen->options = xconfigOptionListDup(screen0->options); + if (screen0->comment) screen->comment = nvstrdup(screen0->comment); + + /* insert the new screen after the original screen */ + + screen->next = screen0->next; + screen0->next = screen; + + return screen; + +} /* clone_screen() */ + + + +/* + * create_adjacencies() - loop through all the screens in the config, + * and add an adjacency section to the layout; this assumes that there + * are no existing adjacencies in the layout + */ + +static void create_adjacencies(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + XConfigAdjacencyPtr adj, prev_adj; + XConfigScreenPtr screen; + int i; + + i = 0; + prev_adj = NULL; + + for (screen = config->screens; screen; screen = screen->next) { + + adj = nvalloc(sizeof(XConfigAdjacencyRec)); + + adj->scrnum = i; + adj->screen_name = nvstrdup(screen->identifier); + adj->screen = screen; + + if (prev_adj) { + prev_adj->next = adj; + } else { + layout->adjacencies = adj; + } + + prev_adj = adj; + i++; + } + + xconfigGenerateAssignScreenAdjacencies(layout); + +} /* create_adjacencies() */ + + +/* + * enable_all_gpus() - get information for every GPU in the system, + * and create a screen section for each + * + * XXX do we add new screens with reasonable defaults, or do we clone + * the first existing X screen N times? For now, we'll just add all + * new X screens + */ + +static int enable_all_gpus(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + DevicesPtr pDevices; + int i; + + pDevices = find_devices(op); + if (!pDevices) { + nv_error_msg("Unable to determine number of GPUs in system; cannot " + "honor '--enable-all-gpus' option."); + return FALSE; + } + + /* free all existing X screens, monitors, devices, and adjacencies */ + + xconfigFreeScreenList(&config->screens); + xconfigFreeDeviceList(&config->devices); + xconfigFreeMonitorList(&config->monitors); + xconfigFreeAdjacencyList(&layout->adjacencies); + + /* add N new screens; this will also add device and monitor sections */ + + for (i = 0; i < pDevices->nDevices; i++) { + xconfigGenerateAddScreen(config, + pDevices->devices[i].dev.bus, + pDevices->devices[i].dev.domain, + pDevices->devices[i].dev.slot, + pDevices->devices[i].name, i, + "nvidia", "NVIDIA Corporation"); + } + + free_devices(pDevices); + + /* create adjacencies for the layout */ + + create_adjacencies(op, config, layout); + + return TRUE; + +} /* enable_all_gpus() */ + + + +/* + * free_unused_devices() - free unused device sections + */ + +static void free_unused_devices(Options *op, XConfigPtr config) +{ + XConfigDevicePtr device, prev, next; + XConfigScreenPtr screen; + int found; + + /* free any unused device sections */ + + device = config->devices; + prev = NULL; + + while (device) { + found = FALSE; + + for (screen = config->screens; screen; screen = screen->next) { + if (device == screen->device) { + found = TRUE; + break; + } + } + + if (!found) { + if (prev) { + prev->next = device->next; + } else { + config->devices = device->next; + } + next = device->next; + device->next = NULL; + xconfigFreeDeviceList(&device); + device = next; + } else { + prev = device; + device = device->next; + } + } +} /* free_unused_devices() */ + + + +/* + * free_unused_monitors() - free unused monitor sections + */ + +static void free_unused_monitors(Options *op, XConfigPtr config) +{ + XConfigMonitorPtr monitor, prev, next; + XConfigScreenPtr screen; + int found; + + /* free any unused monitor sections */ + + monitor = config->monitors; + prev = NULL; + + while (monitor) { + found = FALSE; + + for (screen = config->screens; screen; screen = screen->next) { + if (monitor == screen->monitor) { + found = TRUE; + break; + } + } + + if (!found) { + if (prev) { + prev->next = monitor->next; + } else { + config->monitors = monitor->next; + } + next = monitor->next; + monitor->next = NULL; + xconfigFreeMonitorList(&monitor); + monitor = next; + } else { + prev = monitor; + monitor = monitor->next; + } + } +} /* free_unused_monitors() */ + + + +/* + * only_one_screen() - delete all screens after the first one + */ + +static int only_one_screen(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + if (!config->screens) return FALSE; + + /* free all existing X screens after the first */ + + xconfigFreeScreenList(&config->screens->next); + + /* free all adjacencies */ + + xconfigFreeAdjacencyList(&layout->adjacencies); + + /* add new adjacency */ + + create_adjacencies(op, config, layout); + + /* removed unused device and monitor sections */ + + free_unused_devices(op, config); + free_unused_monitors(op, config); + + return TRUE; + +} /* only_one_screen() */ + diff --git a/nvidia-xconfig-540.3.0/nvidia-cfg.h b/nvidia-xconfig-540.3.0/nvidia-cfg.h new file mode 100644 index 0000000..c0c97a2 --- /dev/null +++ b/nvidia-xconfig-540.3.0/nvidia-cfg.h @@ -0,0 +1,456 @@ +/* + * nvidia-cfg + * + * Copyright (c) 2004 NVIDIA Corp. All rights reserved. + * + * NOTICE TO USER: The source code is copyrighted under U.S. and + * international laws. NVIDIA, Corp. of Santa Clara, California owns + * the copyright and as design patents pending on the design and + * interface of the NV chips. Users and possessors of this source + * code are hereby granted a nonexclusive, royalty-free copyright + * and design patent license to use this code in individual and + * commercial software. + * + * Any use of this source code must include, in the user documenta- + * tion and internal comments to the code, notices to the end user + * as follows: + * + * Copyright (c) 2004 NVIDIA Corp. NVIDIA design patents pending in + * the U.S. and foreign countries. + * + * NVIDIA CORP. MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF + * THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT + * EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORP. DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORP. BE LIABLE + * FOR ANY SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOURCE CODE. + * + * + * This header file defines the public interface to the + * libnvidia-cfg.so library. + */ + +#ifndef __NVIDIA_CFG_H__ +#define __NVIDIA_CFG_H__ + + + +/* + * NvCfgDevice - data structure containing bus:slot pairs + * + * This is deprecated; please use NvCfgPciDevice instead + */ + +typedef struct { + int bus; + int slot; +} NvCfgDevice; + + +/* + * NvCfgPciDevice - data structure identifying a device on the PCI bus + */ + +typedef struct { + int domain; + int bus; + int slot; + int function; +} NvCfgPciDevice; + + +/* + * NvCfgGSyncDeviceType - type of the GSync device + */ + +typedef enum { + NVCFG_TYPE_GSYNC2 = 1, + NVCFG_TYPE_GSYNC3, + NVCFG_TYPE_GSYNC4 +} NvCfgGSyncDeviceType; + + + +#define NV_CFG_GSYNC_DEVICE_FIRMWARE_FORMAT_1 1 + + + +/* + * NvCfgDisplayDeviceInformation - this data structure contains + * various limits and other useful data parsed from the EDID. + */ + +typedef struct { + + /* + * The monitor name is the name of the monitor as specified by an + * EDID 1.x Monitor Descriptors, or an EDID 2.x + * Manufacturer/Product ID string. + */ + + char monitor_name[64]; + + /* + * The horiz_sync and vert_refresh ranges are retrieved from an + * EDID 1.x Monitor Descriptor, or an EDID 2.x Range Limit. + */ + + unsigned int min_horiz_sync; /* in Hz */ + unsigned int max_horiz_sync; /* in Hz */ + unsigned int min_vert_refresh; /* in Hz */ + unsigned int max_vert_refresh; /* in Hz */ + + unsigned int max_pixel_clock; /* in kHz */ + + /* + * The max xres, yres, and refresh, if not 0, are taken from the + * largest mode in the EDID. + */ + + unsigned int max_xres; /* in pixels */ + unsigned int max_yres; /* in pixels */ + unsigned int max_refresh; /* in Hz */ + + /* + * the preferred xres, yres, and refresh, if not 0, are the values + * specified by the EDID as the preferred timing mode of the + * display device. + */ + + unsigned int preferred_xres; /* in pixels */ + unsigned int preferred_yres; /* in pixels */ + unsigned int preferred_refresh; /* in Hz */ + + /* + * the physical width and height, if not 0, are the physical + * dimensions of the display device. + */ + + unsigned int physical_width; /* in mm */ + unsigned int physical_height; /* in mm */ + +} NvCfgDisplayDeviceInformation; + + + +/* + * NvCfgDeviceHandle - this is an opaque handle identifying a + * connection to an NVIDIA VGA adapter. + */ + +typedef void * NvCfgDeviceHandle; + + + +/* + * NvCfgGSyncHandle - this is an opaque handle identifying a + * GSync device. + */ + +typedef void * NvCfgGSyncHandle; + + + +/* + * NvCfg Boolean values + */ + +typedef enum { + NVCFG_TRUE = 1, + NVCFG_FALSE = 0, +} NvCfgBool; + + + +/* + * nvCfgGetDevices() - retrieve an array of NvCfgDevice's indicating + * what PCI devices are present on the system. On success, NVCFG_TRUE + * will be returned, n will contain the number of NVIDIA PCI VGA + * adapters present in the system, and devs will be an allocated array + * containing the bus address of each NVIDIA PCI VGA adapter. When + * the caller is done, it should free the devs array. On failure, + * NVCFG_FALSE will be returned. + * + * This is deprecated; please use nvCfgGetPciDevices() instead. + */ + +NvCfgBool nvCfgGetDevices(int *n, NvCfgDevice **devs); + + + +/* + * nvCfgGetPciDevices() - retrieve an array of NvCfgPciDevice's + * indicating what PCI devices are present on the system. On success, + * NVCFG_TRUE will be returned, n will contain the number of NVIDIA + * PCI graphics devices present in the system, and devs will be an + * allocated array containing the PCI domain:bus:slot:function + * address of each NVIDIA PCI graphics device. When the caller is + * done, it should free the devs array. On failure, NVCFG_FALSE will + * be returned. + */ + +NvCfgBool nvCfgGetPciDevices(int *n, NvCfgPciDevice **devs); + + + +/* + * nvCfgOpenDevice() - open a connection to the NVIDIA device + * identified by the bus:slot PCI address. On success, NVCFG_TRUE + * will be returned and handle be assigned. On failure, NVCFG_FALSE + * will be returned. + * + * This is deprecated; please use nvCfgOpenPciDevice() instead. + */ + +NvCfgBool nvCfgOpenDevice(int bus, int slot, NvCfgDeviceHandle *handle); + + + +/* + * nvCfgAttachPciDevice() - open a limited, display-less connection to + * the NVIDIA device identified by the domain:bus:slot:function PCI + * address. On success, NVCFG_TRUE will be returned and handle will be + * assigned. On failure, NVCFG_FALSE will be returned. + */ +NvCfgBool nvCfgAttachPciDevice(int domain, int bus, int device, int function, + NvCfgDeviceHandle *handle); + + + +/* + * nvCfgOpenPciDevice() - open a connection to the NVIDIA device + * identified by the domain:bus:slot:function PCI address. On + * success, NVCFG_TRUE will be returned and handle will be assigned. + * On failure, NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgOpenPciDevice(int domain, int bus, int device, int function, + NvCfgDeviceHandle *handle); + + + +/* + * nvCfgOpenAllPciDevices() - open a connection to each NVIDIA device + * in the system. On success, NVCFG_TRUE will be returned, n will be + * assigned the number of NVIDIA devices in the system, and handles + * will be assigned with an allocated array of NvCfgDeviceHandles; + * each element in the array is a handle to one of the NVIDIA devices + * in the system. The caller should free the handles array when no + * longer needed. On failure, NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgOpenAllPciDevices(int *n, NvCfgDeviceHandle **handles); + + + +/* + * nvCfgDetachDevice() - close the previously opened limited, display-less + * connection to an NVIDIA device created by nvCfgAttachPciDevice(). + */ +NvCfgBool nvCfgDetachDevice(NvCfgDeviceHandle handle); + + + +/* + * nvCfgCloseDevice() - close the previously opened connection to an + * NVIDIA device created by nvCfgOpenPciDevice(). + */ + +NvCfgBool nvCfgCloseDevice(NvCfgDeviceHandle handle); + + + +/* + * nvCfgCloseAllPciDevices() - close all the NVIDIA device connections + * opened by a previous call to nvCfgOpenAllPciDevices(). + */ + +NvCfgBool nvCfgCloseAllPciDevices(void); + + + +/* + * nvCfgGetNumCRTCs() - return the number of CRTCs (aka "heads") + * present on the specified NVIDIA device. On success, NVCFG_TRUE + * will be returned and crtcs will be assigned. On failure, + * NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgGetNumCRTCs(NvCfgDeviceHandle handle, int *crtcs); + + + +/* + * nvCfgGetProductName() - return an allocated string containing the + * product name of the specified NVIDIA device. It is the caller's + * responsibility to free the returned string. On success, NVCFG_TRUE + * will be returned and name will be assigned. On failure, + * NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgGetProductName(NvCfgDeviceHandle handle, char **name); + + + +/* + * nvCfgGetDeviceUUID() - return an allocated string containing the + * global unique identifier of the specified NVIDIA device. It is the caller's + * responsibility to free the returned string. On success, NVCFG_TRUE + * will be returned and uuid will be assigned. On failure, + * NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgGetDeviceUUID(NvCfgDeviceHandle handle, char **uuid); + + + +/* + * nvCfgGetDisplayDevices() - retrieve a bitmask describing the + * currently connected display devices: this "display device mask" is + * an unsigned 32 bit value that identifies one or more display + * devices. The first 8 bits each identify a CRT, the next 8 bits + * each identify a TV, and the next 8 each identify a DFP. For + * example, 0x1 refers to CRT-0, 0x3 refers to CRT-0 and CRT-1, + * 0x10001 refers to CRT-0 and DFP-0, etc. On success, NVCFG_TRUE + * will be returned and display_device_mask will be assigned. On + * failure, NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgGetDisplayDevices(NvCfgDeviceHandle handle, + unsigned int *display_device_mask); + + + +/* nvCfgGetSupportedDisplayDevices() - get all supported display devices, + * not only connected ones. Interpretation of display_device_mask + * parameter is the same as for nvCfgGetDisplayDevices() call. + * On success, NVCFG_TRUE will be returned and display_device_mask will be + * assigned. On failure, NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgGetSupportedDisplayDevices(NvCfgDeviceHandle handle, + unsigned int *display_device_mask); + + +/* + * nvCfgGetEDIDData() - return an allocated byte array containing the + * EDID for the specified display device, if any. On success, + * NVCFG_TRUE will be returned and edidSize and edid will be assigned. + * On failure, NVCFG_FALSE will be returned. It is the caller's + * responsibility to free the allocated EDID. + */ + +NvCfgBool nvCfgGetEDIDData(NvCfgDeviceHandle handle, + unsigned int display_device, + int *edidSize, void **edid); + + +/* + * nvCfgGetEDIDMonitorData() - Initialize the fields in the + * NvCfgDisplayDeviceInformation data structure, using data from the + * EDID. On success, NVCFG_TRUE will be returned and info will be + * assigned. On failure, NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgGetEDID(NvCfgDeviceHandle handle, + unsigned int display_device, + NvCfgDisplayDeviceInformation *info); + + +/* + * nvCfgIsPrimaryDevice() - determines whether the specified NVIDIA + * device is the primary device. On success, NVCFG_TRUE will be + * returned and is_primary_device set to indicate whether the + * device is the primary device. On failure, NVCFG_FALSE will be + * returned. + */ + +NvCfgBool nvCfgIsPrimaryDevice(NvCfgDeviceHandle handle, + NvCfgBool *is_primary_device); + +/* + * nvCfgGetTeslaSerialNumbers() - returns an allocated array of strings + * containing the serial numbers of all NVIDIA Tesla/QuadroPlex devices + * connected to the host, followed by a NULL character. It is the caller's + * responsibility to free the returned array of strings. On success, + * NVCFG_TRUE will be returned and serials will be assigned. On failure, + * NVCFG_FALSE will be returned. + * + * Note that this function is deprecated and will always return an empty array + * on recent drivers, since QuadroPlex devices are no longer supported. + */ + +NvCfgBool nvCfgGetTeslaSerialNumbers(char ***serials); + + +/* + * nvCfgOpenAllGSyncDevices() - returns an array of NvCfgGSyncHandle's + * indicating what GSync devices are present in the system. On success, + * NVCFG_TRUE will be returned, n will contain the number of GSync devices + * present in the system, and handles will be an allocated array containing + * a handle for each of the GSync devices.The caller should free the + * handles array when no longer needed. On failure, NVCFG_FALSE will be + * returned. + */ + +NvCfgBool nvCfgOpenAllGSyncDevices(int *n, NvCfgGSyncHandle **handles); + + +/* + * nvCfgCloseAllGSyncDevices() - close all the GSync device connections + * opened by a previous call to nvCfgOpenAllGSyncDevices(). + */ + +NvCfgBool nvCfgCloseAllGSyncDevices(void); + + +/* + * nvCfgGetGSyncDeviceType() - returns the type of GSync device referenced + * by handle. + */ + +NvCfgGSyncDeviceType nvCfgGetGSyncDeviceType(NvCfgGSyncHandle handle); + + +/* + * nvCfgGetGSyncDeviceFirmwareVersion() - returns the firmware major version of + * the GSync device referenced by handle. + */ + +int nvCfgGetGSyncDeviceFirmwareVersion(NvCfgGSyncHandle handle); + + +/* + * nvCfgGetGSyncDeviceFirmwareMinorVersion() - returns the firmware minor + * version of the GSync device referenced by handle. + */ + +int nvCfgGetGSyncDeviceFirmwareMinorVersion(NvCfgGSyncHandle handle); + + +/* + * nvCfgFlashGSyncDevice() - flashes the GSync device referenced by handle. + * format contains the firmware format, newFirmwareImage contains the + * new firmware image to be flashed, and size contains the size of + * newFirmwareImage. On success, NVCFG_TRUE will be returned. + * On failure, NVCFG_FALSE will be returned. + */ + +NvCfgBool nvCfgFlashGSyncDevice(NvCfgGSyncHandle handle, int format, + const unsigned char *newFirmwareImage, + int size); + + +/* + * nvCfgDumpDisplayPortAuxLog() - dump the DisplayPort AUX channel log to the + * system log. On success, NVCFG_TRUE will be returned. On failure, NVCFG_FALSE + * will be returned. + */ +NvCfgBool nvCfgDumpDisplayPortAuxLog(NvCfgDeviceHandle handle); + +#endif /* __NVIDIA_CFG__ */ diff --git a/nvidia-xconfig-540.3.0/nvidia-xconfig.1.m4 b/nvidia-xconfig-540.3.0/nvidia-xconfig.1.m4 new file mode 100644 index 0000000..3e60bbf --- /dev/null +++ b/nvidia-xconfig-540.3.0/nvidia-xconfig.1.m4 @@ -0,0 +1,113 @@ +dnl This file is to be preprocessed by m4. +changequote([[[, ]]])dnl +define(__OPTIONS__, [[[include([[[options.1.inc]]])dnl]]])dnl +dnl Solaris man chokes on three-letter macros. +ifelse(__BUILD_OS__,SunOS,[[[define(__URL__,UR)]]],[[[define(__URL__,URL)]]])dnl +.\" Copyright (C) 2005-2010 NVIDIA Corporation. +.\" +__HEADER__ +.\" Define the .__URL__ macro and then override it with the www.tmac package if it +.\" exists. +.de __URL__ +\\$2 \(la \\$1 \(ra\\$3 +.. +.if \n[.g] .mso www.tmac +.TH nvidia\-xconfig 1 "__DATE__" "nvidia\-xconfig __VERSION__" +.SH NAME +nvidia-xconfig \- manipulate X configuration files for the NVIDIA driver +.SH SYNOPSIS +.B nvidia-xconfig +[ +.I options +] +.SH DESCRIPTION +.PP +.B nvidia-xconfig +is a tool intended to provide basic control over configuration options available in the NVIDIA X driver. +.PP +.B nvidia-xconfig +performs its operations in several steps: +.TP +1) +The system X configuration file is found and read into memory. +If no configuration file can be found, +.B nvidia-xconfig +generates one from scratch using default settings; in this case, +.B nvidia-xconfig +will write the configuration to +.I /etc/X11/xorg.conf +.TP +2) +The configuration in memory is modified to support the NVIDIA driver. +This consists of changing the display driver to "nvidia", removing the commands to load the "GLcore" and "dri" modules, and adding the command to load the "glx" module. +.TP +3) +The configuration in memory is modified according to the options specified on the command line. +Please see the NVIDIA README for a description of the NVIDIA X configuration file options. +Note that +.B nvidia-xconfig +does not perform any validation of the X configuration file options requested on the command line; +X configuration file option validation is left for the NVIDIA X driver. +.TP +4) +The configuration is written back to the file from which it was read. +A backup of the original configuration is created with "\.backup" appended. +For example, if your X configuration is +.I /etc/X11/xorg.conf +then +.B nvidia-xconfig +will copy it to +.I /etc/X11/xorg.conf.backup +before writing the new configuration. +The +.B \-\-post\-tree (\-T) +option can be used to print the new configuration to standard out in tree form instead. +This option is useful to see what +.B nvidia-xconfig +will do while leaving the original configuration intact. +.PP +The source code to +.B nvidia\-xconfig +is released under the GPL and available here: +.sp +.ti +5 +.__URL__ "https://download.nvidia.com/XFree86/nvidia-xconfig/" +.sp +Patches are welcome. +dnl Call gen-manpage-opts to generate this section. +__OPTIONS__ +.SH EXAMPLES +.TP +.B nvidia-xconfig +Reads an existing X config file and adapts it to use the NVIDIA driver. +If no X config file can be found, a new one is created at /etc/X11/xorg.conf with default settings. +.TP +.B nvidia-xconfig \-\-post\-tree \-\-metamode\-orientation=clone +Reads the existing X configuration file, adds the MetaModeOrientation option, and then prints the resulting config file to standard out in tree form. +The configuration file is not modified. +.TP +.B nvidia-xconfig \-\-enable\-all\-gpus +Examines the system and configures an X screen for each display device it finds. +.TP +.BI "nvidia-xconfig \-\-mode=" 1600x1200 +Adds a 1600x1200 mode to an existing X configuration. +.TP +.BI "nvidia-xconfig \-\-mode-list=" "1600x1200 1280x1024" +Removes any existing modes from the X configuration file, replacing them with "1600x1200" and "1280x1024". +.TP +.BI "nvidia-xconfig \-\-metamodes=" "1024x768 +0+0, 1024x768 +1024+0" +Adds the MetaMode "1024x768 +0+0, 1024x768 +1024+0" to the existing X configuration file, replacing any existing MetaModes X configuration option. +.TP +.B nvidia-xconfig \-\-only\-one\-x\-screen \-\-sli=Auto +Configures the X server to have just one X screen that will use SLI when available. +.\" .SH FILES +.\" .I /etc/X11/xorg.conf +.SH AUTHOR +Aaron Plattner +.br +NVIDIA Corporation +.SH "SEE ALSO" +.BR nvidia-settings (1), +.I /usr/share/doc/NVIDIA_GLX-1.0/README.txt +.SH COPYRIGHT +Copyright \(co 2005-2010 NVIDIA Corporation. diff --git a/nvidia-xconfig-540.3.0/nvidia-xconfig.c b/nvidia-xconfig-540.3.0/nvidia-xconfig.c new file mode 100644 index 0000000..40ca027 --- /dev/null +++ b/nvidia-xconfig-540.3.0/nvidia-xconfig.c @@ -0,0 +1,1354 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2005 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * nvidia-xconfig.c + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nvidia-xconfig.h" +#include "nvgetopt.h" +#include "msg.h" + +#define TAB " " +#define BIGTAB " " + +#define ORIG_SUFFIX ".nvidia-xconfig-original" +#define BACKUP_SUFFIX ".backup" + + +/* + * print_version() - print version information + */ + +static void print_version(void) +{ + nv_info_msg(NULL, ""); + nv_info_msg(NULL, "%s", NV_ID_STRING); + nv_info_msg(TAB, "The NVIDIA X Configuration Tool."); + nv_info_msg(NULL, ""); + nv_info_msg(TAB, "This program is used to manipulate X configuration files, " + "specifically to enable NVIDIA X driver functionality."); + nv_info_msg(NULL, ""); +} /* print_version() */ + + +static void print_summary(void) +{ + nv_info_msg(NULL, ""); + nv_info_msg(TAB, "In its normal operation, nvidia-xconfig finds the system " + "X configuration file (or generates a new X configuration " + "if it cannot find the system file), makes sure the " + "configuration is usable by the NVIDIA X driver, applies " + "any updates requested on the commandline, and writes the " + "new configuration to file."); + nv_info_msg(NULL, ""); + nv_info_msg(TAB, "Please see the NVIDIA README for a description of NVIDIA " + "X configuration file options."); + nv_info_msg(NULL, ""); +} + + +#include "option_table.h" + + +/* + * print_help() - loop through the __options[] table, and print the + * description of each option. + */ + +static void print_help_helper(const char *name, const char *description) +{ + nv_info_msg(TAB, "%s", name); + nv_info_msg(BIGTAB, "%s", description); + nv_info_msg(NULL, ""); +} + +static void print_help(int advanced) +{ + unsigned int include_mask = 0; + + print_version(); + print_summary(); + + nv_info_msg(NULL, ""); + nv_info_msg(NULL, "nvidia-xconfig [options]"); + nv_info_msg(NULL, ""); + + if (!advanced) { + /* only print options with the ALWAYS flag */ + include_mask |= NVGETOPT_HELP_ALWAYS; + } + + nvgetopt_print_help(__options, include_mask, print_help_helper); +} + + + +/* + * parse_commandline() - malloc an Options structure, initialize it, + * and fill in any pertinent data from the commandline arguments + */ + +static void parse_commandline(Options *op, int argc, char *argv[]) +{ + int c, boolval; + char *strval; + int intval, disable; + double doubleval; + + + while (1) { + + c = nvgetopt(argc, argv, __options, &strval, + &boolval, &intval, &doubleval, &disable); + + if (c == -1) + break; + + /* catch the boolean options */ + + if ((c >= XCONFIG_BOOL_OPTION_START) && + (c <= (XCONFIG_BOOL_OPTION_START + XCONFIG_BOOL_OPTION_COUNT))) { + + if (!check_boolean_option(op, c - XCONFIG_BOOL_OPTION_START, boolval)) { + goto fail; + } + set_boolean_option(op, c - XCONFIG_BOOL_OPTION_START, boolval); + + continue; + } + + switch (c) { + + case 'v': print_version(); exit(0); break; + case 'c': op->xconfig = strval; break; + case 'o': op->output_xconfig = strval; break; + case 't': op->tree = TRUE; break; + case 'T': op->post_tree = TRUE; break; + case 'h': print_help(FALSE); exit(0); break; + case 'A': print_help(TRUE); exit(0); break; + case 's': nv_set_verbosity(NV_VERBOSITY_WARNING); break; + case 'a': op->enable_all_gpus = TRUE; break; + case '1': op->only_one_screen = TRUE; break; + + case 'd': op->depth = intval; + if ((op->depth != 8) && + (op->depth != 15) && + (op->depth != 16) && + (op->depth != 24) && + (op->depth != 30)) { + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid depth: %d.\n", op->depth); + fprintf(stderr, "\n"); + goto fail; + } + break; + + case LAYOUT_OPTION: op->layout = strval; break; + case SCREEN_OPTION: op->screen = strval; break; + case DEVICE_OPTION: op->device = strval; break; + case BUSID_OPTION: + if (GET_BOOL_OPTION(op->boolean_option_values, ENABLE_PRIME_OPTION)) { + fprintf(stderr, "Unable to disable BUSID with PRIME enabled.\n"); + goto fail; + } + op->busid = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case X_PREFIX_OPTION: op->gop.x_project_root = strval; break; + + case KEYBOARD_OPTION: op->gop.keyboard = strval; break; + case KEYBOARD_LIST_OPTION: op->keyboard_list = TRUE; break; + case KEYBOARD_DRIVER_OPTION: op->gop.keyboard_driver = strval; break; + + case MOUSE_OPTION: op->gop.mouse = strval; break; + case MOUSE_LIST_OPTION: op->mouse_list = TRUE; break; + + case NVIDIA_CFG_PATH_OPTION: op->nvidia_cfg_path = strval; break; + + case FORCE_GENERATE_OPTION: op->force_generate = TRUE; break; + + case ACPID_SOCKET_PATH_OPTION: + if (disable) { + op->acpid_socket_path = NV_DISABLE_STRING_OPTION; + } else { + op->acpid_socket_path = strval; + } + break; + + case HANDLE_SPECIAL_KEYS_OPTION: + { + const char *valid_values[] = { + "Always", + "Never", + "WhenNeeded", + NULL, + }; + + int i; + + if (disable) { + op->handle_special_keys = NV_DISABLE_STRING_OPTION; + break; + } + + for (i = 0; valid_values[i]; i++) { + if (!strcasecmp(strval, valid_values[i])) { + break; + } + } + + if (valid_values[i]) { + op->handle_special_keys = strval; + } else { + fprintf(stderr, "Invalid HandleSpecialKeys option: %s.\n", strval); + goto fail; + } + break; + } + + case TRANSPARENT_INDEX_OPTION: + + /* mark as disabled, so we can remove the option later */ + + if (disable) { + op->transparent_index = -2; + break; + } + + if (intval < 0 || intval > 255) { + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid transparent index: %d.\n", intval); + fprintf(stderr, "\n"); + goto fail; + } + op->transparent_index = intval; + break; + + case TV_STANDARD_OPTION: + + { + const char* valid_values[] = { + "PAL-B", + "PAL-D", + "PAL-G", + "PAL-H", + "PAL-I", + "PAL-K1", + "PAL-M", + "PAL-N", + "PAL-NC", + "NTSC-J", + "NTSC-M", + "HD480i", + "HD480p", + "HD720p", + "HD1080i", + "HD1080p", + "HD576i", + "HD576p", + NULL + }; + int i; + + /* mark as disabled, so we can remove the option later */ + + if (disable) { + op->tv_standard = NV_DISABLE_STRING_OPTION; + break; + } + + for (i = 0; valid_values[i]; i++) { + if (!strcasecmp(strval, valid_values[i])) + break; + } + + if (valid_values[i]) { + op->tv_standard = strval; + } else { + fprintf(stderr, "Invalid TVStandard option: %s.\n", strval); + goto fail; + } + } + break; + + case TV_OUT_FORMAT_OPTION: + + /* mark as disabled, so we can remove the option later */ + + if (disable) { + op->tv_out_format = NV_DISABLE_STRING_OPTION; + break; + } + + if (!strcasecmp(strval, "SVIDEO")) { + op->tv_out_format = "SVIDEO"; + } else if (!strcasecmp(strval, "COMPOSITE")) { + op->tv_out_format = "COMPOSITE"; + } else { + fprintf(stderr, "Invalid TVOutFormat option: %s.\n", strval); + goto fail; + } + break; + + case COOL_BITS_OPTION: + + /* mark as disabled, so we can remove the option later */ + + if (disable) { + op->cool_bits = -2; + break; + } + + op->cool_bits = intval; + break; + + case STEREO_OPTION: + + /* mark as disabled, so we can remove the option later */ + + if (disable) { + op->stereo = -2; + break; + } + + if (intval < 0 || intval > 14) { + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid stereo: %d.\n", intval); + fprintf(stderr, "\n"); + goto fail; + } + op->stereo = intval; + break; + + case MODE_OPTION: + if (boolval) { + /* add this mode */ + nv_text_rows_append(&op->add_modes, strval); + } else { + /* remove this mode */ + nv_text_rows_append(&op->remove_modes, strval); + } + break; + + case MODE_LIST_OPTION: + { + char *token; + token = strtok(strval, " "); + if (!token) { + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid Mode List string: %s.\n", strval); + fprintf(stderr, "\n"); + goto fail; + } + do { + nv_text_rows_append(&op->add_modes_list, token); + token = strtok(NULL, " "); + } while (token != NULL); + + break; + } + + case REMOVE_MODE_OPTION: + nv_text_rows_append(&op->remove_modes, strval); + break; + + case META_MODES_OPTION: + op->metamodes_str = strval; + break; + + case MULTI_GPU_OPTION: /* fall through */ + case SLI_OPTION: + { + const char* valid_values[] = { + "0", + "no", + "off", + "false", + "single", + "mosaic", + NULL + }; + + if (disable) { + + /* mark as disabled, so we can remove the option later */ + strval = NV_DISABLE_STRING_OPTION; + + } else { + + /* check that the string is valid */ + int i; + + for (i = 0; valid_values[i]; i++) { + if (!strcasecmp(strval, valid_values[i])) + break; + } + + if (!valid_values[i]) { + fprintf(stderr, "Invalid SLI option: %s.\n", strval); + goto fail; + } + } + + if (c == MULTI_GPU_OPTION) { + op->multigpu = strval; + } else { + op->sli = strval; + } + } + break; + + case PRESERVE_DRIVER_NAME_OPTION: op->preserve_driver = TRUE; break; + + case DISABLE_SCF_OPTION: op->disable_scf = TRUE; break; + + case QUERY_GPU_INFO_OPTION: op->query_gpu_info = TRUE; break; + + case 'E': + op->extract_edids_from_file = strval; + break; + + case EXTRACT_EDIDS_OUTPUT_FILE_OPTION: + op->extract_edids_output_file = strval; + break; + + case NVIDIA_XINERAMA_INFO_ORDER_OPTION: + op->nvidia_xinerama_info_order = + disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case METAMODE_ORIENTATION_OPTION: + { + const char* valid_values[] = { + "RightOf", + "LeftOf", + "Above", + "Below", + "Clone", + NULL + }; + int i; + + if (disable) { + op->metamode_orientation = NV_DISABLE_STRING_OPTION; + break; + } + + for (i = 0; valid_values[i]; i++) { + if (!strcasecmp(strval, valid_values[i])) + break; + } + + if (!valid_values[i]) { + fprintf(stderr, "Invalid MetaModeOrientation option: " + "\"%s\".\n", strval); + goto fail; + } + + op->metamode_orientation = strval; + } + break; + + case VIRTUAL_OPTION: + { + int ret, x, y; + + if (disable) { + op->virtual.x = op->virtual.y = -1; + break; + } + + ret = sscanf(strval, "%dx%d", &x, &y); + + if (ret != 2) { + fprintf(stderr, "Invalid Virtual option: \"%s\".\n", + strval); + goto fail; + } + + op->virtual.x = x; + op->virtual.y = y; + + break; + } + + case USE_DISPLAY_DEVICE_OPTION: + op->use_display_device = + disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case CUSTOM_EDID_OPTION: + op->custom_edid = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case CONNECTED_MONITOR_OPTION: + op->connected_monitor = + disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case REGISTRY_DWORDS_OPTION: + op->registry_dwords = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case COLOR_SPACE_OPTION: + op->color_space = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case COLOR_RANGE_OPTION: + op->color_range = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case FLATPANEL_PROPERTIES_OPTION: + op->flatpanel_properties = + disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case NVIDIA_3DVISION_USB_PATH_OPTION: + op->nvidia_3dvision_usb_path = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case NVIDIA_3DVISIONPRO_CONFIG_FILE_OPTION: + op->nvidia_3dvisionpro_config_file = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case NVIDIA_3DVISION_DISPLAY_TYPE_OPTION: + + /* mark as disabled, so we can remove the option later */ + + if (disable) { + op->nvidia_3dvision_display_type = -2; + break; + } + + if (intval < 0 || intval > 2) { + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid 3D Vision display type option: %d.\n", intval); + fprintf(stderr, "\n"); + goto fail; + } + op->nvidia_3dvision_display_type = intval; + break; + + case RESTORE_ORIGINAL_BACKUP_OPTION: + op->restore_original_backup = TRUE; + break; + + case NUM_X_SCREENS_OPTION: + + if (intval < 1) { + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid number of X screens: %d.\n", intval); + fprintf(stderr, "\n"); + goto fail; + } + + /* Enable separate X screens */ + set_boolean_option(op, + XCONFIG_BOOL_VAL(SEPARATE_X_SCREENS_BOOL_OPTION) - + XCONFIG_BOOL_OPTION_START, TRUE); + + op->num_x_screens = intval; + break; + + case FORCE_COMPOSITION_PIPELINE_OPTION: + op->force_composition_pipeline = + disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case FORCE_FULL_COMPOSITION_PIPELINE_OPTION: + op->force_full_composition_pipeline = + disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + case ALLOW_HMD_OPTION: + op->allow_hmd = disable ? NV_DISABLE_STRING_OPTION : strval; + break; + + default: + goto fail; + } + } + + /* do tilde expansion on the filenames given */ + + op->xconfig = tilde_expansion(op->xconfig); + op->output_xconfig = tilde_expansion(op->output_xconfig); + + return; + + fail: + + fprintf(stderr, "\n"); + fprintf(stderr, "Invalid commandline, please run `%s --help` " + "for usage information.\n", argv[0]); + fprintf(stderr, "\n"); + exit(1); + +} /* parse_commandline() */ + + + +/* + * load_default_options - malloc an Options structure + * and initialize it with default values. + * + */ + +static Options *load_default_options(void) +{ + Options *op; + + op = (Options *) nvalloc(sizeof(Options)); + if (!op) return NULL; + + op->depth = 24; + op->transparent_index = -1; + op->stereo = -1; + op->cool_bits = -1; + op->nvidia_3dvision_display_type = -1; + op->tv_over_scan = -1.0; + op->num_x_screens = -1; + + xconfigGenerateLoadDefaultOptions(&op->gop); + + /* + * XXX save the option structure so that printing routines can + * access it (and so that we don't have to carry the op everywhere + * just so that we can pass it to printing routines). + */ + { + extern Options *__op; + + __op = op; + } + + return op; + +} /* load_default_options() */ + + + +/* + * backup_file() - create a backup of orig_filename, naming the backup + * file ".". + * + * XXX If we fail to write to the backup file (eg, it is in a + * read-only directory), then we should do something intelligent like + * write the backup to the user's home directory. + */ + +static int backup_file(Options *op, const char *orig_filename, + const char *suffix) +{ + char *filename; + int ret = FALSE; + + /* construct the backup filename */ + + filename = nvstrcat(orig_filename, suffix, NULL); + + /* if the backup file already exists, remove it */ + + if (access(filename, F_OK) == 0) { + if (unlink(filename) != 0) { + nv_error_msg("Unable to create backup file '%s' (%s)", + filename, strerror(errno)); + goto done; + } + } + + /* copy the file */ + + if (!copy_file(orig_filename, filename, 0644)) { + /* copy_file() prints out its own error messages */ + goto done; + } + + nv_info_msg(NULL, "Backed up file '%s' as '%s'", orig_filename, filename); + ret = TRUE; + + done: + + free(filename); + + return ret; + +} /* backup_file() */ + + + +/* + * find_xconfig() - search for an X config file. + * + * We search for the filename is this order: + * + * 1) "--output-xconfig" option + * + * 2) config->filename + * + * 3) use xf86openConfigFile() + */ + +static char *find_xconfig(Options *op, XConfigPtr config) +{ + char *filename = NULL; + + /* 1) "--output-xconfig" option */ + + if (op->output_xconfig) { + filename = nvstrdup(op->output_xconfig); + } + + /* config->filename */ + + if (!filename && config && config->filename) { + filename = nvstrdup(config->filename); + } + + /* use xf86openConfigFile() */ + + if (!filename) { + const char *f; + f = xconfigOpenConfigFile(NULL, op->gop.x_project_root); + if (f) { + /* dup the string since closing the config file will free + the string */ + filename = nvstrdup(f); + xconfigCloseConfigFile(); + } + } + + if (!filename) { + filename = nvstrdup("/etc/X11/xorg.conf"); + } + + return filename; +} /* find_xconfig() */ + + +/* + * restore_backup - search for a backup file with the given suffix; + * if one is found, restore it. + */ +static int restore_backup(Options *op, XConfigPtr config, const char *suffix) +{ + char *filename = find_xconfig(op, config); + char *backup = nvstrcat(filename, suffix, NULL); + struct stat st; + int ret = FALSE; + + if (lstat(backup, &st) != 0) { + nv_error_msg("Unable to restore from original backup file '%s' (%s)", + backup, strerror(errno)); + goto done; + } + + /* + * do not restore files if the permissions might allow a malicious user to + * modify the backup, potentially tricking an administrator into restoring + * the modified backup. + */ + if (!S_ISREG(st.st_mode) /* non-regular files */ || + st.st_uid != 0 /* not owned by root*/ || + (st.st_gid != 0 && (st.st_mode & S_IWGRP)) /* non-root group write */ || + (st.st_mode & S_IWOTH) /* world writable */ ) { + nv_error_msg("The permissions of the original backup file '%s' are too " + "loose to be trusted. The file will not be restored.", backup); + goto done; + } + + /* + * if the backup is empty, assume that no original x config file existed + * and delete the current X config file. + */ + + if (st.st_size == 0) { + if (unlink(filename) != 0) { + nv_error_msg("Unable to remove file '%s' (%s)", + filename, strerror(errno)); + goto done; + } + } else { + /* copy the file */ + + if (!copy_file(backup, filename, 0644)) { + /* copy_file() prints out its own error messages */ + goto done; + } + } + + /* remove backup: a new one is created if nvidia-xconfig is run again */ + + if (access(backup, F_OK) == 0) { + if (unlink(backup) != 0) { + nv_error_msg("Unable to remove backup file '%s' (%s)", + backup, strerror(errno)); + goto done; + } + } + + if (st.st_size == 0) { + nv_info_msg(NULL, "The backup file '%s' was empty. This usually means " + "that nvidia-xconfig did not find an X configuration " + "file the first time it was run. The X configuration " + "file '%s' was deleted.", + backup, filename); + } else { + nv_info_msg(NULL, "Restored backup file '%s' to '%s'", backup, filename); + } + + ret = TRUE; + + done: + + free(backup); + free(filename); + + return ret; +} /* restore_backup() */ + + + +/* + * write_xconfig() - write the Xconfig to file. + */ + +static int write_xconfig(Options *op, XConfigPtr config, int first_touch) +{ + char *filename = find_xconfig(op, config); + char *d, *tmp = NULL; + int ret = FALSE; + + /* + * XXX it's strange that lack of permission to write to the target + * location (the likely case with users not having write + * permission on /etc/X11/ will fail at backup time, rather than + * when we try to write the new file. Perhaps we should backup to + * a temporary location where we know we will have write access, + * try to do the write, and only if we succeed in the write, move + * the backup file into place. + */ + + /* check that we can write to this location */ + + tmp = nvstrdup(filename); + d = dirname(tmp); + if (access(d, W_OK) != 0) { + nv_error_msg("Unable to write to directory '%s'.", d); + goto done; + } + + /* + * if the file already exists, create a backup first. if this is our first + * time writing the x config, create a separate "original" backup file. + */ + + if (access(filename, F_OK) == 0) { + if (first_touch && !backup_file(op, filename, ORIG_SUFFIX)) goto done; + if (!backup_file(op, filename, BACKUP_SUFFIX)) goto done; + } + + /* + * if no file exists, and this is our first time writing the x config, back + * up an empty file to use as the "original" backup. + */ + + else if (first_touch) { + char *fakeorig = nvstrcat(filename, ORIG_SUFFIX, NULL); + if (!copy_file("/dev/null", fakeorig, 0644)) { + nv_warning_msg("Unable to write an empty backup file \"%s\".", + fakeorig); + } + free(fakeorig); + } + + /* write the config file */ + + if (!xconfigWriteConfigFile(filename, config)) { + nv_error_msg("Unable to write file \"%s\"; please use the " + "\"--output-xconfig\" commandline option to specify " + "an alternative output file.", filename); + goto done; + } + + nv_info_msg(NULL, "New X configuration file written to '%s'", filename); + nv_info_msg(NULL, ""); + + + /* Set the default depth in the Solaris Management Facility + * to the default depth of the first screen + */ + if (op->disable_scf == FALSE) { + if (!update_scf_depth(config->screens[0].defaultdepth)) { + goto done; + } + } + + ret = TRUE; + + done: + + if (filename) free(filename); + if (tmp) free(tmp); + + return ret; + +} /* write_xconfig() */ + + + +/* + * find_banner_prefix() - helper for update_banner(); like + * 'strstr("# nvidia-xconfig:")' but allows arbitrary whitespace between + * '#' and 'n'. + */ + +static char *find_banner_prefix(char *str) +{ + char *s, *comment = NULL; + + for (s = str; s && *s; s++) { + char c = *s; + + /* + * if we aren't presently looking at a comment, and we found the + * start of a comment, then save it and goto the next char + */ + + if ((!comment) && (c == '#')) { + comment = s; + continue; + } + + if (comment) { + /* ignore space within the comment */ + if (isspace(c)) { + continue; + } + /* if the prefix matches, then return the start of the comment */ + if (strncmp(s, "nvidia-xconfig:", 15) == 0) { + return comment; + } + } + + /* anything else forces us out of any current comment */ + comment = NULL; + } + return NULL; + +} /* find_banner_prefix() */ + + + +/* + * update_banner() - add our banner at the top of the config, but + * first we need to remove any lines that already include our prefix + * (because presumably they are a banner from an earlier run of + * nvidia-xconfig) + */ + +static void update_banner(XConfigPtr config) +{ + static const char *banner = + "X configuration file generated by nvidia-xconfig\n"; + static const char *prefix = + "# nvidia-xconfig: "; + + char *s = config->comment; + char *line, *eol, *tmp; + + /* remove all lines that begin with the prefix */ + + while (s && (line = find_banner_prefix(s))) { + + eol = strchr(line, '\n'); /* find the end of the line */ + + if (eol) { + eol++; + if (*eol == '\0') eol = NULL; + } + + if (line == s) { /* the line with the prefix is at the start */ + if (eol) { /* there is more after the prefix line */ + tmp = strdup(eol); + free(s); + s = tmp; + } else { /* the prefix line is the only line */ + free(s); + s = NULL; + } + } else { /* prefix line is in the middle or end */ + *line = '\0'; + tmp = nvstrcat(s, eol, NULL); + free(s); + s = tmp; + } + } + + /* add our prefix lines at the start of the comment */ + + config->comment = nvstrcat(prefix, banner, "# " NV_ID_STRING "\n", s, NULL); + + if (s) free(s); + +} /* update_banner() */ + + + +/* + * find_system_xconfig() - find the system X config file and parse it; + * returns XConfigPtr if successful, otherwise returns NULL. + */ + +static XConfigPtr find_system_xconfig(Options *op) +{ + const char *filename; + XConfigPtr config; + XConfigError error; + + /* Find and open the existing X config file */ + + filename = xconfigOpenConfigFile(op->xconfig, op->gop.x_project_root); + + if (filename) { + nv_info_msg(NULL, ""); + nv_info_msg(NULL, "Using X configuration file: \"%s\".", filename); + } else { + nv_warning_msg("Unable to locate/open X configuration file."); + return NULL; + } + + /* Read the opened X config file */ + + error = xconfigReadConfigFile(&config); + if (error != XCONFIG_RETURN_SUCCESS) { + xconfigCloseConfigFile(); + return NULL;; + } + + /* Close the X config file */ + + xconfigCloseConfigFile(); + + /* Sanitize the X config file */ + + if (!xconfigSanitizeConfig(config, op->screen, &(op->gop))) { + xconfigFreeConfig(&config); + return NULL; + } + + return config; + +} /* find_system_xconfig() */ + + + +/* + * apply_enable_prime_settings() - if the ENABLE PRIME boolean option is + * enabled, add the required xconfig additions. + * returns a success/fail boolean. + */ + +static int apply_enable_prime_settings(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + DevicesPtr pDevices; + + if (GET_BOOL_OPTION(op->boolean_option_values, ENABLE_PRIME_OPTION)) { + /* Add an inactive device for the integrated graphics */ + pDevices = find_devices(op); + if (!pDevices) { + nv_error_msg("Unable to find any GPUs in the system."); + return FALSE; + } + xconfigAddInactiveDevice(config, layout, pDevices->nDevices); + + nv_info_msg(NULL, "X Configuration file set up for PRIME. Please run " + "\"xrandr --setprovideroutputsource modesetting " + "NVIDIA-0\" and \"xrandr --auto\" to enable. " + "See the README for more details."); + } + return TRUE; +} /* apply_enable_prime_settings() */ + +/* + * apply_enable_external_gpu_option() - if the ENABLE EXTERNAL GPU boolean + * option is enabled, add the AllowExternalGpus option to the ServerLayout + * section + * returns a success/fail boolean + */ + +static int apply_enable_external_gpu_option(Options *op, XConfigPtr config, + XConfigLayoutPtr layout) +{ + int egpu = GET_BOOL_OPTION(op->boolean_option_values, + ENABLE_EXTERNAL_GPU_BOOL_OPTION); + + if (GET_BOOL_OPTION(op->boolean_options, ENABLE_EXTERNAL_GPU_BOOL_OPTION)) { + xconfigAddNewOption(&(layout->options), + "AllowExternalGpus", + (egpu ? "1" : "0")); + + if (egpu) { + nv_info_msg(NULL, "X configuration file set up to allow detection " + "of External GPUs. If the eGPU does not work, " + "you may need to authorize the associated " + "Thunderbolt device.\n" + "Warning: System may become unstable if the " + "eGPU is hot-unplugged while X is running.\n" + "See \"Configuring External and Removable " + "GPUs\" in the README for more details."); + } + } + return TRUE; +} /* apply_enable_external_gpu_option */ + + +static int update_xconfig(Options *op, XConfigPtr config) +{ + XConfigLayoutPtr layout; + XConfigAdjacencyPtr adj; + int updated; + + /* get the layout to update */ + + layout = get_layout(op, config); + if (!layout) { + return FALSE; + } + + /* apply multi-display options */ + + if (!apply_multi_screen_options(op, config, layout)) { + return FALSE; + } + + /* apply PRIME settings */ + + if (!apply_enable_prime_settings(op, config, layout)) { + return FALSE; + } + + /* apply eGPU setting */ + if (!apply_enable_external_gpu_option(op, config, layout)) { + return FALSE; + } + + /* + * update the device and option for all screens, or the screen + * or device that was requested. + */ + updated = FALSE; + + for (adj = layout->adjacencies; adj; adj = adj->next) { + + if (!adj->screen) { + continue; + } + + /* if screen option set: skip adj if not the requested screen */ + + if ((op->screen) && + (xconfigNameCompare(op->screen, adj->screen->identifier) != 0)) { + continue; + } + + /* if device option set: skip adj if not the requested device */ + + if ((op->device) && + (xconfigNameCompare(op->device, adj->screen->device_name) != 0)) { + continue; + } + + update_screen(op, config, adj->screen); + updated = TRUE; + } + + if (op->screen && !updated) { + nv_error_msg("Unable to find screen '%s'", op->screen); + return FALSE; + } + + if (op->device && !updated) { + nv_error_msg("Unable to find device '%s'", op->device); + return FALSE; + } + + update_extensions(op, config); + + update_modules(config); + + update_server_flags(op, config); + + update_banner(config); + + return TRUE; + +} /* update_xconfig() */ + + + +/* + * main program entry point + * + * The intended behavior is that, by default, nvidia-xconfig make the + * system's X config file usable by the NVIDIA X driver. If + * nvidia-xconfig cannot file the system's X config file, then it + * attempts to create one and make that usable. + * + * + */ + +int main(int argc, char *argv[]) +{ + Options *op; + int ret; + XConfigPtr config = NULL; + int first_touch = 0; + + /* Load defaults */ + + op = load_default_options(); + if (!op) { + fprintf(stderr, "\nOut of memory error.\n\n"); + return 1; + } + + /* parse the commandline */ + + parse_commandline(op, argc, argv); + + /* + * first, check for any of special options that cause us to exit + * early + */ + + if (op->keyboard_list) { + nv_info_msg(NULL, "\nPossible keyboard types; the short name is what " + "should be passed to the \"--keyboard\" option.\n\n"); + xconfigGeneratePrintPossibleKeyboards(); + return 0; + } + + if (op->mouse_list) { + nv_info_msg(NULL, "\nPossible mouse types; the short name is what should " + "be passed to the \"--mouse\" option.\n\n"); + xconfigGeneratePrintPossibleMice(); + return 0; + } + + if (op->query_gpu_info) { + ret = query_gpu_info(op); + return (ret ? 0 : 1); + } + + if (op->extract_edids_from_file) { + ret = extract_edids(op); + return (ret ? 0 : 1); + } + + if (op->restore_original_backup) { + config = find_system_xconfig(op); + xconfigGetXServerInUse(&op->gop); + ret = restore_backup(op, config, ORIG_SUFFIX); + return (ret ? 0 : 1); + } + + /* + * we want to open and parse the system's existing X config file, + * if possible + */ + + if (!op->force_generate) { + config = find_system_xconfig(op); + } + + /* + * pass the system config (if any) to the tree printer + */ + + if (op->tree) { + ret = print_tree(op, config); + return (ret ? 0 : 1); + } + + /* + * Get which X server is in use: Xorg or XFree86 + */ + xconfigGetXServerInUse(&op->gop); + + /* + * if we failed to find the system's config file, generate a new + * one + */ + + if (!config) { + config = xconfigGenerate(&op->gop); + first_touch = 1; + } + + /* + * if we don't have a valid config by now, something catestrophic + * happened + */ + + if (!config) { + nv_error_msg("Unable to generate a usable X configuration file."); + return 1; + } + + /* if a config file existed, check to see if it had an nvidia-xconfig + * banner: this would suggest that we've touched this file before. + */ + + if (!first_touch) { + first_touch = (find_banner_prefix(config->comment) == NULL); + } + + /* now, we have a good config; apply whatever the user requested */ + + update_xconfig(op, config); + + /* print the config in tree format, if requested */ + + if (op->post_tree) { + ret = print_tree(op, config); + return (ret ? 0 : 1); + } + + /* write the config back out to file */ + + if (!write_xconfig(op, config, first_touch)) { + return 1; + } + + return 0; + +} /* main() */ diff --git a/nvidia-xconfig-540.3.0/nvidia-xconfig.h b/nvidia-xconfig-540.3.0/nvidia-xconfig.h new file mode 100644 index 0000000..be7d13c --- /dev/null +++ b/nvidia-xconfig-540.3.0/nvidia-xconfig.h @@ -0,0 +1,246 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2004 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * nvidia-xconfig.h + */ + +#ifndef __NVIDIA_XCONFIG_H__ +#define __NVIDIA_XCONFIG_H__ + +#include "xf86Parser.h" +#include "nvidia-cfg.h" +#include "common-utils.h" + +#include + + +/* Boolean options */ +#define UBB_BOOL_OPTION 1 +#define RENDER_ACCEL_BOOL_OPTION 2 +#define NO_RENDER_EXTENSION_BOOL_OPTION 3 +#define OVERLAY_BOOL_OPTION 4 +#define CIOVERLAY_BOOL_OPTION 5 +#define OVERLAY_DEFAULT_VISUAL_BOOL_OPTION 6 +#define NO_POWER_CONNECTOR_CHECK_BOOL_OPTION 8 +#define ALLOW_GLX_WITH_COMPOSITE_BOOL_OPTION 10 +#define SEPARATE_X_SCREENS_BOOL_OPTION 13 +#define XINERAMA_BOOL_OPTION 14 +#define NVIDIA_XINERAMA_INFO_BOOL_OPTION 15 +#define NOFLIP_BOOL_OPTION 16 +#define DAC_8BIT_BOOL_OPTION 17 +#define USE_EDID_FREQS_BOOL_OPTION 18 +#define USE_EDID_BOOL_OPTION 19 +#define FORCE_STEREO_FLIPPING_BOOL_OPTION 21 +#define MULTISAMPLE_COMPATIBILITY_BOOL_OPTION 22 +#define EXACT_MODE_TIMINGS_DVI_BOOL_OPTION 24 +#define ADD_ARGB_GLX_VISUALS_BOOL_OPTION 27 +#define COMPOSITE_BOOL_OPTION 28 +#define DISABLE_GLX_ROOT_CLIPPING_BOOL_OPTION 29 +#define USE_EDID_DPI_BOOL_OPTION 30 +#define DAMAGE_EVENTS_BOOL_OPTION 31 +#define CONSTANT_DPI_BOOL_OPTION 32 +#define PROBE_ALL_GPUS_BOOL_OPTION 33 +#define INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION 34 +#define USE_EVENTS_BOOL_OPTION 35 +#define CONNECT_TO_ACPID_BOOL_OPTION 36 +#define MODE_DEBUG_BOOL_OPTION 37 +#define THERMAL_CONFIGURATION_CHECK_BOOL_OPTION 38 +#define PRESERVE_BUSID_BOOL_OPTION 39 +#define BASE_MOSAIC_BOOL_OPTION 40 +#define ALLOW_EMPTY_INITIAL_CONFIGURATION 41 +#define INBAND_STEREO_SIGNALING 42 +#define FORCE_YUV_420 43 +#define ENABLE_PRIME_OPTION 44 +#define ENABLE_EXTERNAL_GPU_BOOL_OPTION 45 + +#define XCONFIG_BOOL_OPTION_COUNT (ENABLE_EXTERNAL_GPU_BOOL_OPTION + 1) + +/* # of 32-bit variables needed to hold all the boolean options (bits) */ +#define XCONFIG_BOOL_OPTION_SLOTS \ + ((XCONFIG_BOOL_OPTION_COUNT)/32) + \ + (((XCONFIG_BOOL_OPTION_COUNT)%32)?1:0) + +#define GET_BOOL_OPTION_SLOT(BLOCKS, VAR) \ + ((BLOCKS)[(u32)((VAR)/32)]) + +#define GET_BOOL_OPTION_BIT(VAR) \ + (1<<(u32)((VAR)%32)) + +#define GET_BOOL_OPTION(BLOCKS, VAR) \ + (GET_BOOL_OPTION_SLOT((BLOCKS), (VAR)) & \ + GET_BOOL_OPTION_BIT(VAR)) + + +/* define to store in string options */ +#define NV_DISABLE_STRING_OPTION ((void *) -1) + +/* 32 bit unsigned variable (used to pack booleans) */ +typedef unsigned int u32; + + +typedef struct __options { + int force_generate; + int tree; + int post_tree; + int keyboard_list; + int mouse_list; + int enable_all_gpus; + int only_one_screen; + int disable_scf; + int query_gpu_info; + int preserve_driver; + int restore_original_backup; + + /* + * the option parser will set bits in boolean_options to indicate + * whether an option was set, and will then turn the corresponding + * bit in boolean_option_values on or off to indicate if the + * option was true or false. + */ + + u32 boolean_options[XCONFIG_BOOL_OPTION_SLOTS]; + u32 boolean_option_values[XCONFIG_BOOL_OPTION_SLOTS]; + + int depth; + int transparent_index; + int stereo; + int cool_bits; + int nvidia_3dvision_display_type; + + int num_x_screens; + + char *xconfig; + char *output_xconfig; + char *layout; + char *screen; + char *device; + char *busid; + char *multigpu; + char *sli; + + char *nvidia_cfg_path; + char *extract_edids_from_file; + char *extract_edids_output_file; + char *nvidia_xinerama_info_order; + char *metamode_orientation; + char *use_display_device; + char *custom_edid; + char *tv_standard; + char *tv_out_format; + char *acpid_socket_path; + char *handle_special_keys; + char *connected_monitor; + char *registry_dwords; + char *metamodes_str; + char *color_space; + char *color_range; + char *flatpanel_properties; + char *nvidia_3dvision_usb_path; + char *nvidia_3dvisionpro_config_file; + char *force_composition_pipeline; + char *force_full_composition_pipeline; + char *allow_hmd; + + double tv_over_scan; + + struct { + int x; + int y; + } virtual; + + TextRows add_modes; + TextRows add_modes_list; + TextRows remove_modes; + + GenerateOptions gop; + +} Options; + +/* data structures for storing queried GPU information */ + +typedef struct _display_device_rec { + NvCfgDisplayDeviceInformation info; + int info_valid; + unsigned int mask; +} DisplayDeviceRec, *DisplayDevicePtr; + +typedef struct _device_rec { + NvCfgPciDevice dev; + NvCfgDeviceHandle handle; + int crtcs; + char *name; + char *uuid; + unsigned int displayDeviceMask; + int nDisplayDevices; + DisplayDevicePtr displayDevices; +} DeviceRec, *DevicePtr; + +typedef struct { + int nDevices; + DevicePtr devices; +} DevicesRec, *DevicesPtr; + + +/* util.c */ + +int copy_file(const char *srcfile, const char *dstfile, mode_t mode); +char *nv_format_busid(Options *op, int index); + +/* make_usable.c */ + +int update_modules(XConfigPtr config); +int update_screen(Options *op, XConfigPtr config, XConfigScreenPtr screen); +XConfigLayoutPtr get_layout(Options *op, XConfigPtr config); +int update_extensions(Options *op, XConfigPtr config); +int update_server_flags(Options *op, XConfigPtr config); + +/* multiple_screens.c */ + +DevicesPtr find_devices(Options *op); +void free_devices(DevicesPtr devs); + +int apply_multi_screen_options(Options *op, XConfigPtr config, + XConfigLayoutPtr layout); + +/* tree.c */ + +int print_tree(Options *op, XConfigPtr config); + +/* options.c */ + +int check_boolean_option(Options *op, const int c, const int boolval); +void set_boolean_option(Options *op, const int c, const int boolval); +void validate_composite(Options *op, XConfigPtr config); +void update_options(Options *op, XConfigScreenPtr screen); + +/* lscf.c */ +int update_scf_depth(int depth); +int read_scf_depth(int *depth); + +/* query_gpu_info.c */ + +int query_gpu_info(Options *op); + +/* extract_edids.c */ + +int extract_edids(Options *op); + + + +#endif /* __NVIDIA_XCONFIG_H__ */ diff --git a/nvidia-xconfig-540.3.0/option_table.h b/nvidia-xconfig-540.3.0/option_table.h new file mode 100644 index 0000000..a36894b --- /dev/null +++ b/nvidia-xconfig-540.3.0/option_table.h @@ -0,0 +1,680 @@ +/* + * Options table; the fields are: + * + * name - this is the long option name + * + * shortname - this is the one character short option name + * + * flags - bitmask; see NVGETOPT_ constants in nvgetopt.h + * + * description - text for use by print_help() to describe the option + */ + +#include "nvidia-xconfig.h" + +enum { + SCREEN_OPTION = 1024, + LAYOUT_OPTION, + X_PREFIX_OPTION, + KEYBOARD_OPTION, + KEYBOARD_LIST_OPTION, + KEYBOARD_DRIVER_OPTION, + MOUSE_OPTION, + FORCE_GENERATE_OPTION, + MOUSE_LIST_OPTION, + MODE_OPTION, + MODE_LIST_OPTION, + REMOVE_MODE_OPTION, + NVIDIA_CFG_PATH_OPTION, + SLI_OPTION, + DISABLE_SCF_OPTION, + TRANSPARENT_INDEX_OPTION, + STEREO_OPTION, + QUERY_GPU_INFO_OPTION, + EXTRACT_EDIDS_OUTPUT_FILE_OPTION, + MULTI_GPU_OPTION, + NVIDIA_XINERAMA_INFO_ORDER_OPTION, + METAMODE_ORIENTATION_OPTION, + VIRTUAL_OPTION, + USE_DISPLAY_DEVICE_OPTION, + CUSTOM_EDID_OPTION, + TV_STANDARD_OPTION, + TV_OUT_FORMAT_OPTION, + TV_OVER_SCAN_OPTION, + COOL_BITS_OPTION, + ACPID_SOCKET_PATH_OPTION, + HANDLE_SPECIAL_KEYS_OPTION, + PRESERVE_DRIVER_NAME_OPTION, + CONNECTED_MONITOR_OPTION, + REGISTRY_DWORDS_OPTION, + META_MODES_OPTION, + COLOR_SPACE_OPTION, + COLOR_RANGE_OPTION, + BUSID_OPTION, + DEVICE_OPTION, + FLATPANEL_PROPERTIES_OPTION, + NVIDIA_3DVISION_USB_PATH_OPTION, + NVIDIA_3DVISIONPRO_CONFIG_FILE_OPTION, + NVIDIA_3DVISION_DISPLAY_TYPE_OPTION, + RESTORE_ORIGINAL_BACKUP_OPTION, + NUM_X_SCREENS_OPTION, + FORCE_COMPOSITION_PIPELINE_OPTION, + FORCE_FULL_COMPOSITION_PIPELINE_OPTION, + ALLOW_HMD_OPTION, +}; + +/* + * To add a boolean option to nvidia-xconfig: + * + * 1) Add the definition of the constant to the "Boolean options" list + * in nvidia-xconfig.h + * + * 2) add an entry in the below (alphabetized) __options[] table; for + * the second field in the __options[] table, specify + * XCONFIG_BOOL_VAL() + * + * 3) add an entry to the __options[] table at the top of options.c + * with the constant and the option name as it should appear in the X + * config file. + * + * nvidia-xconfig.c:parse_commandline() will record in + * op->boolean_options whether the commandline option was specified, + * and will record in op->boolean_option_values whether the option was + * specified to be true or false. options.c:update_options() will + * apply your boolean option to the X config file. + */ + + +#define XCONFIG_BOOL_OPTION_START 128 + + +/* + * The XCONFIG_BOOL_VAL() macro packs boolean options into the val + * field of the __option[] table; these are above 128, so that + * isalpha(3) returns FALSE for them. + */ + +#define XCONFIG_BOOL_VAL(x) (XCONFIG_BOOL_OPTION_START + (x)) + + +static const NVGetoptOption __options[] = { + /* These options are printed by "nvidia-xconfig --help" */ + + { "xconfig", 'c', NVGETOPT_STRING_ARGUMENT | NVGETOPT_HELP_ALWAYS, NULL, + "Use &XCONFIG& as the input X config file; if this option is not " + "specified, then the same search path used by the X server will be " + "used to find the X configuration file." }, + + { "output-xconfig", 'o', + NVGETOPT_STRING_ARGUMENT | NVGETOPT_HELP_ALWAYS, NULL, + "Use &OUTPUT-XCONFIG& as the output X configuration file; if this " + "option is not specified, then the input X configuration filename will " + "also be used as the output X configuration filename." }, + + { "silent", 's', NVGETOPT_HELP_ALWAYS, NULL, + "Run silently; no messages will be printed to stdout, except for " + "warning and error messages to stderr." }, + + { "tree", 't', NVGETOPT_HELP_ALWAYS, NULL, + "Read the X configuration file, print to stdout the X " + "configuration data in a tree format, and exit." }, + + { "version", 'v', NVGETOPT_HELP_ALWAYS, NULL, + "Print the nvidia-xconfig version and exit." }, + + { "help", 'h', NVGETOPT_HELP_ALWAYS, NULL, + "Print usage information for the common commandline options and exit." }, + + { "advanced-help", 'A', NVGETOPT_HELP_ALWAYS, NULL, + "Print usage information for the common commandline options as well " + "as the advanced options, and then exit." }, + + /* These options are only printed by "nvidia-xconfig --advanced-help" */ + + { "acpid-socket-path", + ACPID_SOCKET_PATH_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Set this option to specify an alternate path to the Linux ACPI daemon " + "(acpid)'s socket, which the NVIDIA X driver will use to connect to " + "acpid." }, + + { "add-argb-glx-visuals", + XCONFIG_BOOL_VAL(ADD_ARGB_GLX_VISUALS_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enables or disables support for OpenGL rendering into 32-bit ARGB " + "windows and pixmaps." }, + + { "allow-glx-with-composite", + XCONFIG_BOOL_VAL(ALLOW_GLX_WITH_COMPOSITE_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"AllowGLXWithComposite\" X configuration " + "option." }, + + { "busid", BUSID_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "This option writes the specified BusID to the device section of the " + "X configuration file. If there are multiple device sections, then it " + "adds the BusID field to each of them. To add the BusID to only a " + "specific device or screen section, use the '--device' or '--screen' " + "options." }, + + { "preserve-busid", XCONFIG_BOOL_VAL(PRESERVE_BUSID_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "By default, nvidia-xconfig preserves the existing BusID in the X " + "configuration file only if there are multiple X screens configured " + "for the X server. Use '--preserve-busid' or '--no-preserve-busid' to " + "force the BusID to be preserved or not preserved, overriding the " + "default behavior." }, + + { "cool-bits", COOL_BITS_OPTION, + NVGETOPT_INTEGER_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the \"Coolbits\" X configuration option. Setting this " + "option will enable support in the NV-CONTROL X extension for manipulating " + "GPU clock and GPU fan control settings. Default value is 0. For fan\n" + "control set it to 4. " + "WARNING: this may cause system damage and void warranties." }, + + { "composite", + XCONFIG_BOOL_VAL(COMPOSITE_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"Composite\" X extension." }, + + { "connected-monitor", CONNECTED_MONITOR_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "CONNECTED-MONITOR", + "Enable or disable the \"ConnectedMonitor\" X configuration option; " + "setting this option forces the X driver to behave as if the specified " + "display devices are connected to the GPU." }, + + { "connect-to-acpid", + XCONFIG_BOOL_VAL(CONNECT_TO_ACPID_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"ConnectToAcpid\" X configuration option. " + "If this option is set, the NVIDIA X driver will attempt to connect " + "to the Linux ACPI daemon (acpid). Set this option to off to prevent " + "the X driver from attempting to connect to acpid." }, + + { "constant-dpi", + XCONFIG_BOOL_VAL(CONSTANT_DPI_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"ConstantDPI\" X configuration option, " + "which controls whether the NVIDIA X driver maintains a constant " + "dots per inch (DPI) value by recomputing the reported size in " + "millimeters of the X screen when XRandR changes the size in pixels " + "of the X screen." }, + + { "custom-edid", CUSTOM_EDID_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "CUSTOM-EDID", + "Enable or disable the \"CustomEDID\" X configuration option; " + "setting this option forces the X driver to use the EDID specified." + "This option is a semicolon-separated list of pairs of display device names " + "and filename pairs; e.g \"CRT-0:\\tmp\\edid.bin\". Note that a display " + "device name must always be specified even if only one EDID is" + " specified. " }, + + { "dac-8bit", XCONFIG_BOOL_VAL(DAC_8BIT_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Most Quadro parts by default use a 10 bit color look up table (LUT) " + "by default; setting this option to TRUE forces these graphics chips " + "to use an 8 bit (LUT)." }, + + { "depth", 'd', NVGETOPT_INTEGER_ARGUMENT, NULL, + "Set the default depth to &DEPTH&; valid values for &DEPTH& are " + "8, 15, 16, 24, and 30." }, + + { "device", DEVICE_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, + "The nvidia-xconfig utility operates on one or more devices in " + "the X configuration file. If this option is specified, the " + "device named &DEVICE& in the X configuration file will be " + "used. If this option is not specified, all the devices within " + "the X configuration file will be used." }, + + { "disable-glx-root-clipping", + XCONFIG_BOOL_VAL(DISABLE_GLX_ROOT_CLIPPING_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, "Disable or enable clipping OpenGL rendering " + "to the root window via the \"DisableGLXRootClipping\" " + "X configuration option." }, + + { "damage-events", + XCONFIG_BOOL_VAL(DAMAGE_EVENTS_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, "Use OS-level events to notify the X server " + "when a direct-rendering client has performed rendering that needs to be " + "composited to the screen. Improves performance when using GLX with the " + "composite extension." }, + +#if defined(NV_SUNOS) + { "disable-scf", DISABLE_SCF_OPTION, 0, NULL, + "On Solaris, nvidia-xconfig updates the service configuration " + "repository with the default depth being set in the X configuration " + "file. The property 'default_depth' of the group 'options' in the " + "selection 'application/x11/x11-server' is set to the default depth. " + "Use this option to disable the service configuration repository " + "update." }, +#endif + + { "preserve-driver-name", PRESERVE_DRIVER_NAME_OPTION, 0, NULL, + "By default nvidia-xconfig changes the display driver to \"nvidia\" " + "for all configured X screens; this option preserves the existing driver " + "name of each X screen." }, + + { "egpu", XCONFIG_BOOL_VAL(ENABLE_EXTERNAL_GPU_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"AllowExternalGpus\" X configuration option." }, + + { "enable-all-gpus", 'a', 0, NULL, + "Delete all existing X screens in the current configuration, " + "then configure an X screen on every GPU in your system." }, + + { "exact-mode-timings-dvi", + XCONFIG_BOOL_VAL(EXACT_MODE_TIMINGS_DVI_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Forces the initialization of the X server with " + "the exact timings specified in the ModeLine." }, + + { "extract-edids-from-file", 'E', NVGETOPT_STRING_ARGUMENT, "FILE", + "Extract any raw EDID byte blocks contained in the specified X " + "log file &LOG&; raw EDID bytes are printed by the NVIDIA X driver to " + "the X log as hexadecimal when verbose logging is enabled with the " + "\"-logverbose 6\" X server commandline option. Any extracted EDIDs " + "are then written as binary data to individual files. These files " + "can later be used by the NVIDIA X driver through the \"CustomEDID\" " + "X configuration option." }, + + { "extract-edids-output-file", + EXTRACT_EDIDS_OUTPUT_FILE_OPTION, NVGETOPT_STRING_ARGUMENT, "FILENAME", + "When the '--extract-edids-from-file' option is used, nvidia-xconfig " + "writes any extracted EDID to a file, typically \"edid.bin\" in the " + "current directory. Use this option to specify an alternate " + "filename. Note that nvidia-xconfig, if necessary, will append a " + "unique number to the EDID filename, to avoid overwriting existing " + "files (e.g., \"edid.bin.1\" if \"edid.bin\" already exists)." }, + + { "flatpanel-properties", FLATPANEL_PROPERTIES_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Set the flat panel properties. The supported properties are " + "'dithering' and 'ditheringmode'. Please see the NVIDIA " + "README 'Appendix B. X Config Options' for more details on the " + "possible values and syntax." }, + + { "flip", XCONFIG_BOOL_VAL(NOFLIP_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable OpenGL flipping" }, + + { "force-generate", FORCE_GENERATE_OPTION, 0, NULL, + "Force generation of a new X config file, ignoring any existing " + "system X config file. This is not typically recommended, as things " + "like the mouse protocol, keyboard layout, font paths, etc, are setup " + "by your Unix distribution. While nvidia-xconfig can attempt to " + "infer these values, it is best to use your Unix distribution's " + "X config file for the basis of anything that nvidia-xconfig creates." }, + + { "force-stereo-flipping", + XCONFIG_BOOL_VAL(FORCE_STEREO_FLIPPING_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Normally, stereo flipping is only performed when a stereo drawable is " + "visible. This option forces stereo flipping even when no stereo " + "drawables are visible." }, + + { "handle-special-keys", HANDLE_SPECIAL_KEYS_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "WHEN", + "Specify when the X server should use the builtin keyboard handler to " + "process special key combinations (such as Ctrl+Alt+Backspace); see " + "the X configuration man page for details. The value of &WHEN& can be " + "'Always', 'Never', or 'WhenNeeded'." }, + + { "include-implicit-metamodes", + XCONFIG_BOOL_VAL(INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"IncludeImplicitMetaModes\" X configuration " + "option." }, + + { "keyboard", KEYBOARD_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, + "When generating a new X configuration file (which happens when no " + "system X configuration file can be found, or the '--force-generate' " + "option is specified), use &KEYBOARD& as the keyboard type, rather " + "than attempting to probe the system for the keyboard type. " + "For a list of possible keyboard types, see the '--keyboard-list' " + "option." }, + + { "keyboard-driver", KEYBOARD_DRIVER_OPTION, + NVGETOPT_STRING_ARGUMENT, "DRIVER", + "In most cases nvidia-xconfig can automatically determine the correct " + "keyboard driver to use (either 'kbd' or 'keyboard'). Use this " + "option to override what nvidia-xconfig detects. Typically, if you are " + "using an X.Org X server, use 'kdb'; if you are using an XFree86 X " + "server, use 'keyboard'." }, + + { "keyboard-list", KEYBOARD_LIST_OPTION, 0, NULL, + "Print to stdout the available keyboard types recognized by the " + "'--keyboard' option, and then exit." }, + + { "layout", LAYOUT_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, + "The nvidia-xconfig utility operates on a Server Layout within the X " + "configuration file. If this option is specified, the layout named " + "&LAYOUT& in the X configuration file will be used. If this option is " + "not specified, the first Server Layout in the X configuration " + "file is used." }, + + { "mode", + MODE_OPTION, NVGETOPT_IS_BOOLEAN | NVGETOPT_STRING_ARGUMENT, NULL, + "Add the specified mode to the mode list." }, + + { "mode-debug", XCONFIG_BOOL_VAL(MODE_DEBUG_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"ModeDebug\" X configuration option; when " + "enabled, this option causes the X driver to print verbose details " + "about mode validation to the X log file." }, + + { "mode-list", MODE_LIST_OPTION, NVGETOPT_STRING_ARGUMENT, "MODELIST", + "Remove all existing modes from the X configuration's modelist and " + "add the one(s) specified in the &MODELIST& string." }, + + { "remove-mode", REMOVE_MODE_OPTION, NVGETOPT_STRING_ARGUMENT, "MODE", + "Remove the specified mode from the mode list." }, + + { "metamodes", META_MODES_OPTION, NVGETOPT_STRING_ARGUMENT, "METAMODES", + "Add the MetaMode X configuration option with the value &METAMODES& " + "which will replace any existing MetaMode option already in the X " + "configuration file." }, + + { "mouse", MOUSE_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, + "When generating a new X configuration file (which happens when no " + "system X configuration file can be found, or the '--force-generate' " + "option is specified), use &MOUSE& as the mouse type, rather than " + "attempting to probe the system for the mouse type. For a list of " + "possible mouse types, see the '--mouse-list' option." }, + + { "mouse-list", MOUSE_LIST_OPTION, 0, NULL, + "Print to stdout the available mouse types recognized by the " + "'--mouse' option, and then exit." }, + + { "multigpu", MULTI_GPU_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable MultiGPU. Valid values for &MULTIGPU& are " + "'Off' and 'Mosaic'." }, + + { "multisample-compatibility", + XCONFIG_BOOL_VAL(MULTISAMPLE_COMPATIBILITY_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the use of separate front and " + "back multisample buffers." }, + + { "nvidia-cfg-path", + NVIDIA_CFG_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, "PATH", + "The nvidia-cfg library is used to communicate with the NVIDIA kernel " + "module to query basic properties of every GPU in the system. This " + "library is typically only used by nvidia-xconfig when configuring " + "multiple X screens. This option tells nvidia-xconfig where to look " + "for this library (in case it cannot find it on its own). This option " + "should normally not be needed." }, + + { "only-one-x-screen", '1', 0, NULL, + "Disable all but one X screen." }, + + { "overlay", + XCONFIG_BOOL_VAL(OVERLAY_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"Overlay\" X configuration option." }, + + { "cioverlay", + XCONFIG_BOOL_VAL(CIOVERLAY_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the color index overlay." }, + + { "overlay-default-visual", + XCONFIG_BOOL_VAL(OVERLAY_DEFAULT_VISUAL_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"OverlayDefaultVisual\" " + "X configuration option." }, + + { "transparent-index", TRANSPARENT_INDEX_OPTION, + NVGETOPT_INTEGER_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "INDEX", + "Pixel to use as transparent when using color index overlays. " + "Valid values for &TRANSPARENT-INDEX& are 0-255."}, + + { "post-tree", 'T', 0, NULL, + "Like the '--tree' option, but goes through the full process of " + "applying any user requested updates to the X configuration, before " + "printing the final configuration to stdout in a tree format. " + "Effectively, this option just causes the configuration to be printed " + "to stdout as a tree instead of writing the results to file." }, + + { "power-connector-check", + XCONFIG_BOOL_VAL(NO_POWER_CONNECTOR_CHECK_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Disable or enable the \"NoPowerConnectorCheck\" " + "X configuration option." }, + + { "probe-all-gpus", XCONFIG_BOOL_VAL(PROBE_ALL_GPUS_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Disable or enable the \"ProbeAllGpus\" X configuration option." }, + + { "query-gpu-info", QUERY_GPU_INFO_OPTION, 0, NULL, + "Print information about all recognized NVIDIA GPUs in the system." }, + + { "registry-dwords", REGISTRY_DWORDS_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the \"RegistryDwords\" X configuration option." }, + + { "render-accel", + XCONFIG_BOOL_VAL(RENDER_ACCEL_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"RenderAccel\" X configuration option." }, + + { "render-extension", + XCONFIG_BOOL_VAL(NO_RENDER_EXTENSION_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Disable or enable the \"NoRenderExtension\" X configuration option." }, + + { "screen", SCREEN_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, + "The nvidia-xconfig utility operates on one or more screens within a " + "Server Layout in the X configuration file. If this option is " + "specified, the screen named &SCREEN& in the X configuration file will " + "be used. If this option is not specified, all screens within the " + "selected Server Layout in the X configuration file " + "will be used used." }, + + { "separate-x-screens", + XCONFIG_BOOL_VAL(SEPARATE_X_SCREENS_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "A GPU that supports multiple simultaneous display devices can either " + "drive these display devices in a single X screen, or as separate X " + "screens. When the '--separate-x-screens' option is specified, each GPU " + "on which an X screen is currently configured will be updated to have " + "two or more (depending on the capabilities of that GPU) X screens " + "configured. The '--no-separate-x-screens' option will remove any " + "extra configured X screens on each GPU. Please see the NVIDIA README " + "description of \"Separate X Screens on One GPU\" for further details." }, + + { "x-screens-per-gpu", NUM_X_SCREENS_OPTION, + NVGETOPT_INTEGER_ARGUMENT, NULL, + "A GPU that supports multiple simultaneous display devices can either " + "drive these display devices in a single X screen, or as separate X " + "screens. When the '--x-screens-per-gpu=' option is " + "specified, each GPU on which an X screen is currently configured will " + "be updated to have X screens. has to be greater " + "than 0. Setting to 1 is equivalent to specifying the " + "'--no-separate-x-screens' option. Please see the NVIDIA README " + "description of \"Separate X Screens on One GPU\" for further details." }, + + { "sli", SLI_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable SLI. Valid values for &SLI& are 'Off' and 'Mosaic'." }, + + { "stereo", STEREO_OPTION, + NVGETOPT_INTEGER_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the stereo mode. Valid values for &STEREO& are: 0 " + "(Disabled), 1 (DDC glasses), 2 (Blueline glasses), 3 (Onboard stereo), " + "4 (multi-display clone mode stereo), 5 (SeeReal digital flat panel), 6 " + "(Sharp3D digital flat panel), 7 (Arisawa/Hyundai/Zalman/Pavione/Miracube), " + "8 (3D DLP), 9 (3D DLP INV), 10 (NVIDIA 3D VISION), " + "11 (NVIDIA 3D VISION PRO), 12 (HDMI 3D), 13 (Tridelity SL)." }, + + { "thermal-configuration-check", + XCONFIG_BOOL_VAL(THERMAL_CONFIGURATION_CHECK_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Disable or enable the \"ThermalConfigurationCheck\" " + "X configuration option." }, + + { "tv-standard", TV_STANDARD_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "TV-STANDARD", + "Enable or disable the \"TVStandard\" X configuration option. Valid " + "values for \"TVStandard\" are: \"PAL-B\", \"PAL-D\", \"PAL-G\", " + "\"PAL-H\", \"PAL-I\", \"PAL-K1\", \"PAL-M\", \"PAL-N\", \"PAL-NC\", " + "\"NTSC-J\", \"NTSC-M\", \"HD480i\", \"HD480p\", \"HD720p\", " + "\"HD1080i\", \"HD1080p\", \"HD576i\", \"HD576p\"." }, + + { "tv-out-format", TV_OUT_FORMAT_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "TV-OUT-FORMAT", + "Enable or disable the \"TVOutFormat\" X configuration option. Valid " + "values for \"TVOutFormat\" are: \"SVIDEO\" and \"COMPOSITE\"." }, + + { "metamode-orientation", METAMODE_ORIENTATION_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "ORIENTATION", + "Specify the MetaModeOrientation. Valid values for &ORIENTATION& are: " + "\"RightOf\" (the default), \"LeftOf\", \"Above\", \"Below\", or " + "\"Clone\"." }, + + { "nvidia-xinerama-info", + XCONFIG_BOOL_VAL(NVIDIA_XINERAMA_INFO_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable providing Xinerama information from the " + "NVIDIA X driver." }, + + { "nvidia-xinerama-info-order", + NVIDIA_XINERAMA_INFO_ORDER_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the \"nvidiaXineramaInfoOrder\" X configuration " + "option. &NVIDIA-XINERAMA-INFO-ORDER& is a comma-separated list " + "of display device names that describe the order in which " + "nvidiaXineramaInfo should be reported. E.g., \"CRT, DFP, TV\"." }, + + { "ubb", + XCONFIG_BOOL_VAL(UBB_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"UBB\" X configuration option." }, + + { "use-edid", + XCONFIG_BOOL_VAL(USE_EDID_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable use of the EDID (Extended Display Identification " + "Data) from your display device(s). The EDID will be used for driver " + "operations such as building lists of available modes, determining " + "valid frequency ranges, and computing the DPI (Dots Per Inch). " + "This option defaults to TRUE (the NVIDIA X driver will use the EDID, " + "when available). It is NOT recommended that you use this option to " + "globally disable use of the EDID; instead, use '--no-use-edid-freqs' " + "or '--no-use-edid-dpi' to disable specific uses of the EDID." }, + + { "use-edid-dpi", + XCONFIG_BOOL_VAL(USE_EDID_DPI_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable use of the physical size information in the display " + "device's EDID, if any, to compute the DPI (Dots Per Inch) of the X " + "screen. This option defaults to TRUE (the NVIDIA X driver uses the " + "EDID's physical size, when available, to compute the DPI)." }, + + { "use-edid-freqs", + XCONFIG_BOOL_VAL(USE_EDID_FREQS_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable use of the HorizSync and VertRefresh " + "ranges given in a display device's EDID, if any. EDID provided " + "range information will override the HorizSync and VertRefresh ranges " + "specified in the Monitor section. This option defaults to TRUE (the " + "NVIDIA X driver will use frequency information from the EDID, when " + "available)." }, + + { "use-display-device", USE_DISPLAY_DEVICE_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "DISPLAY-DEVICE", + "Force the X driver to use the display device specified." }, + + { "use-events", + XCONFIG_BOOL_VAL(USE_EVENTS_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable \"UseEvents\" X configuration option. Setting this " + "option will enable the X driver to use the system events in some cases " + "when it is waiting for the hardware. With this option X driver sets an " + "event handler and waits for the hardware through the poll() system " + "call. This option defaults to FALSE." }, + + { "virtual", VIRTUAL_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "WIDTHxHEIGHT", + "Specify the virtual screen resolution." }, + + { "x-prefix", X_PREFIX_OPTION, NVGETOPT_STRING_ARGUMENT, NULL, + "The X installation prefix; the default is /usr/X11R6/. Only " + "under rare circumstances should this option be needed." }, + + { "xinerama", XCONFIG_BOOL_VAL(XINERAMA_BOOL_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, "Enable or disable Xinerama." }, + + { "color-space", COLOR_SPACE_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "COLORSPACE", + "Enable or disable the \"ColorSpace\" X configuration option. " + "Valid values for \"COLORSPACE\" are: \"RGB\" and \"YCbCr444\"." }, + + { "color-range", COLOR_RANGE_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "COLORRANGE", + "Sets the \"ColorRange\" X configuration option. " + "Valid values for \"COLORRANGE\" are: \"Full\" and \"Limited\"." }, + + { "3dvision-usb-path", NVIDIA_3DVISION_USB_PATH_OPTION, NVGETOPT_STRING_ARGUMENT, + NULL, "Set this option to specify the sysfs path of the connected " + "USB dongle." }, + + { "3dvisionpro-config-file", NVIDIA_3DVISIONPRO_CONFIG_FILE_OPTION, NVGETOPT_STRING_ARGUMENT, + NULL, "Set this option to specify the NVIDIA 3DVisionPro " + "configuration file. Ensure X server has a read and write access " + "permissions to this file. NVIDIA X driver stores the hub and " + "the pairing configuration in this file to re-use across X restarts. " + "If this option is not provided, 3D VisionPro configuration will not " + "be stored." }, + + { "3dvision-display-type", NVIDIA_3DVISION_DISPLAY_TYPE_OPTION, + NVGETOPT_INTEGER_ARGUMENT | NVGETOPT_ALLOW_DISABLE, + NULL, "When NVIDIA 3D Vision is enabled with a non 3D Vision ready " + "display, use this option to specify the display type. Valid values " + "are: 0 (Assume it is a CRT), 1 (Assume it is a DLP) and " + "2 (Assume it is a DLP TV and enable the checkerboard output)." }, + + { "base-mosaic", + XCONFIG_BOOL_VAL(BASE_MOSAIC_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL, + "Enable or disable the \"BaseMosaic\" X configuration option." }, + + { "restore-original-backup", RESTORE_ORIGINAL_BACKUP_OPTION, 0, NULL, + "Restore a backup of the X configuration that was made before any " + "changes were made by nvidia-xconfig, if such a backup is available. " + "This type of backup is made by nvidia-xconfig before it modifies an " + "X configuration file that it has not previously touched; this is " + "assumed to be an X configuration file that predates the involvement " + "of the NVIDIA X driver. As an example, nvidia-xconfig will copy an " + "X configuration file at /etc/X11/xorg.conf to /etc/X11/xorg.conf." + "nvidia-xconfig-original the first time it makes changes to that file."}, + + { "allow-empty-initial-configuration", XCONFIG_BOOL_VAL(ALLOW_EMPTY_INITIAL_CONFIGURATION), + NVGETOPT_IS_BOOLEAN, NULL, "Allow the X server to start even if no " + "connected display devices could be detected." }, + + { "inband-stereo-signaling", XCONFIG_BOOL_VAL(INBAND_STEREO_SIGNALING), + NVGETOPT_IS_BOOLEAN, NULL, "Enable or disable the " + "\"InbandStereoSignaling\" X configuration option." }, + + { "force-yuv-420", XCONFIG_BOOL_VAL(FORCE_YUV_420), + NVGETOPT_IS_BOOLEAN, NULL, "Enable or disable the " + "\"ForceYUV420\" X configuration option. If the current display and GPU " + "both support uncompressed RGB 4:4:4 output and YUV 4:2:0 compressed " + "output with the current mode, then RGB 4:4:4 output is selected by " + "default. This option forces the use of YUV 4:2:0 output (where " + "supported) instead." }, + + { "force-composition-pipeline", FORCE_COMPOSITION_PIPELINE_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the \"ForceCompositionPipeline\" X " + "configuration option." }, + + { "force-full-composition-pipeline", FORCE_FULL_COMPOSITION_PIPELINE_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the \"ForceFullCompositionPipeline\" X " + "configuration option." }, + + { "allow-hmd", ALLOW_HMD_OPTION, + NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL, + "Enable or disable the \"AllowHMD\" X configuration option." }, + + { "prime", XCONFIG_BOOL_VAL(ENABLE_PRIME_OPTION), + NVGETOPT_IS_BOOLEAN, NULL, + "Enable PRIME for the generated X config file. Cannot be run with " + "--no-busid or --no-allow-empty-initial-configuration. On a system with " + "more than 1 GPU, specify the GPU to use for PRIME with --busid or the " + "first available will be chosen. Note that to enable PRIME it is " + "necessary to run \"xrandr --setprovideroutputsource modesetting " + "NVIDIA-0\" and \"xrandr --auto\" after completion." }, + + { NULL, 0, 0, NULL, NULL }, +}; diff --git a/nvidia-xconfig-540.3.0/options.c b/nvidia-xconfig-540.3.0/options.c new file mode 100644 index 0000000..b726a13 --- /dev/null +++ b/nvidia-xconfig-540.3.0/options.c @@ -0,0 +1,813 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2004 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * options.c + */ + +#include +#include +#include + +#include "nvidia-xconfig.h" +#include "xf86Parser.h" +#include "msg.h" + + +typedef struct { + unsigned int num; + int invert; + const char *name; +} NvidiaXConfigOption; + +static const NvidiaXConfigOption __options[] = { + + { UBB_BOOL_OPTION, FALSE, "UBB" }, + { RENDER_ACCEL_BOOL_OPTION, FALSE, "RenderAccel" }, + { NO_RENDER_EXTENSION_BOOL_OPTION, TRUE, "NoRenderExtension" }, + { OVERLAY_BOOL_OPTION, FALSE, "Overlay" }, + { CIOVERLAY_BOOL_OPTION, FALSE, "CIOverlay" }, + { OVERLAY_DEFAULT_VISUAL_BOOL_OPTION, FALSE, "OverlayDefaultVisual" }, + { NO_POWER_CONNECTOR_CHECK_BOOL_OPTION, TRUE, "NoPowerConnectorCheck" }, + { THERMAL_CONFIGURATION_CHECK_BOOL_OPTION, FALSE, "ThermalConfigurationCheck" }, + { ALLOW_GLX_WITH_COMPOSITE_BOOL_OPTION, FALSE, "AllowGLXWithComposite" }, + { XINERAMA_BOOL_OPTION, FALSE, "Xinerama" }, + { NVIDIA_XINERAMA_INFO_BOOL_OPTION, FALSE, "nvidiaXineramaInfo" }, + { NOFLIP_BOOL_OPTION, TRUE, "NoFlip" }, + { DAC_8BIT_BOOL_OPTION, FALSE, "Dac8Bit" }, + { USE_EDID_FREQS_BOOL_OPTION, FALSE, "UseEdidFreqs" }, + { USE_EDID_BOOL_OPTION, FALSE, "UseEdid" }, + { FORCE_STEREO_FLIPPING_BOOL_OPTION, FALSE, "ForceStereoFlipping" }, + { MULTISAMPLE_COMPATIBILITY_BOOL_OPTION, FALSE, "MultisampleCompatibility" }, + { EXACT_MODE_TIMINGS_DVI_BOOL_OPTION, FALSE, "ExactModeTimingsDVI" }, + { ADD_ARGB_GLX_VISUALS_BOOL_OPTION, FALSE, "AddARGBGLXVisuals" }, + { DISABLE_GLX_ROOT_CLIPPING_BOOL_OPTION, FALSE, "DisableGLXRootClipping" }, + { USE_EDID_DPI_BOOL_OPTION, FALSE, "UseEdidDpi" }, + { DAMAGE_EVENTS_BOOL_OPTION, FALSE, "DamageEvents" }, + { CONSTANT_DPI_BOOL_OPTION, FALSE, "ConstantDPI" }, + { PROBE_ALL_GPUS_BOOL_OPTION, FALSE, "ProbeAllGpus" }, + { INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION,FALSE, "IncludeImplicitMetaModes" }, + { USE_EVENTS_BOOL_OPTION, FALSE, "UseEvents" }, + { CONNECT_TO_ACPID_BOOL_OPTION, FALSE, "ConnectToAcpid" }, + { MODE_DEBUG_BOOL_OPTION, FALSE, "ModeDebug" }, + { BASE_MOSAIC_BOOL_OPTION, FALSE, "BaseMosaic" }, + { ALLOW_EMPTY_INITIAL_CONFIGURATION, FALSE, "AllowEmptyInitialConfiguration" }, + { INBAND_STEREO_SIGNALING, FALSE, "InbandStereoSignaling" }, + { FORCE_YUV_420, FALSE, "ForceYUV420" }, + { ENABLE_EXTERNAL_GPU_BOOL_OPTION, FALSE, "AllowExternalGpus" }, + { 0, FALSE, NULL }, +}; + + + +/* + * get_option() - get the NvidiaXConfigOption entry for the given + * option index + */ + +static const NvidiaXConfigOption *get_option(const int n) +{ + int i; + + for (i = 0; __options[i].name; i++) { + if (__options[i].num == n) return &__options[i]; + } + return NULL; + +} /* get_option() */ + +/* + * check_boolean_option() - verify the boolean option 'c' can be + * applied given other set options. + */ + +int check_boolean_option(Options *op, const int c, const int boolval) +{ + switch (c) { + + case ENABLE_PRIME_OPTION: + /* + * Prime requires these features, so if the user + * has disabled it we have a conflict. + */ + if (GET_BOOL_OPTION(op->boolean_options, + ALLOW_EMPTY_INITIAL_CONFIGURATION) + && + !GET_BOOL_OPTION(op->boolean_option_values, + ALLOW_EMPTY_INITIAL_CONFIGURATION)) + { + fprintf(stderr, "Unable to enable PRIME with " + "ALLOW_EMPTY_INITIAL_CONFIGURATION disabled.\n"); + return FALSE; + } else if (op->busid == NV_DISABLE_STRING_OPTION) { + fprintf(stderr, "Unable to enable PRIME with BUSID disabled.\n"); + return FALSE; + } + break; + + case ALLOW_EMPTY_INITIAL_CONFIGURATION: + if (GET_BOOL_OPTION(op->boolean_option_values, + ENABLE_PRIME_OPTION) + && !boolval) + { + fprintf(stderr, "Unable to disable" + "ALLOW_EMPTY_INITIAL_CONFIGURATION with" + "PRIME enabled.\n"); + return FALSE; + } + break; + + default: break; + } + + return TRUE; +} + +/* + * set_boolean_option() - set boolean option 'c' to the given 'boolval' + */ + +void set_boolean_option(Options *op, const int c, const int boolval) +{ + u32 bit; + + bit = GET_BOOL_OPTION_BIT(c); + + GET_BOOL_OPTION_SLOT(op->boolean_options, c) |= bit; + + if (boolval) { + GET_BOOL_OPTION_SLOT(op->boolean_option_values, c) |= bit; + + /* Options that must be paired together */ + switch (c) { + case ENABLE_PRIME_OPTION: { + set_boolean_option(op, ALLOW_EMPTY_INITIAL_CONFIGURATION, TRUE); + break; + } + } + } else { + GET_BOOL_OPTION_SLOT(op->boolean_option_values, c) &= ~bit; + } +} /* set_boolean_option() */ + + + +/* + * validate_composite() - check whether any options conflict with the + * Composite extension; update the composite option value, if + * appropriate. + */ + +void validate_composite(Options *op, XConfigPtr config) +{ + int composite_specified; + int xinerama_enabled; + int overlay_enabled; + int cioverlay_enabled; + int ubb_enabled; + int stereo_enabled; + char *err_str; + + + composite_specified = GET_BOOL_OPTION(op->boolean_options, + COMPOSITE_BOOL_OPTION); + + xinerama_enabled = (GET_BOOL_OPTION(op->boolean_options, + XINERAMA_BOOL_OPTION) && + GET_BOOL_OPTION(op->boolean_option_values, + XINERAMA_BOOL_OPTION)); + + overlay_enabled = (GET_BOOL_OPTION(op->boolean_options, + OVERLAY_BOOL_OPTION) && + GET_BOOL_OPTION(op->boolean_option_values, + OVERLAY_BOOL_OPTION)); + + cioverlay_enabled = (GET_BOOL_OPTION(op->boolean_options, + CIOVERLAY_BOOL_OPTION) && + GET_BOOL_OPTION(op->boolean_option_values, + CIOVERLAY_BOOL_OPTION)); + + ubb_enabled = (GET_BOOL_OPTION(op->boolean_options, + UBB_BOOL_OPTION) && + GET_BOOL_OPTION(op->boolean_option_values, + UBB_BOOL_OPTION)); + + stereo_enabled = !!(op->stereo > 0); + + err_str = xconfigValidateComposite(config, + &(op->gop), + composite_specified, + xinerama_enabled, + op->depth, + overlay_enabled, + cioverlay_enabled, + ubb_enabled, + stereo_enabled); + + /* + * if we have to disable the composite extension, print a warning + * and set the option value. + * + * We need to be careful to only set the option value if the X + * server is going to recognize the Extension section and the + * composite option. We guess whether the server will recognize + * the option: if get_xserver_in_use() thinks the X server + * supports the "Composite" extension, or the current config + * already has an extension section, or the user specified the + * composite option. + */ + + if (err_str) { + nv_warning_msg("The Composite X extension does not currently interact " + "well with the %s option(s); the Composite X extension " + "will be disabled.", err_str); + + set_boolean_option(op, COMPOSITE_BOOL_OPTION, FALSE); + nvfree(err_str); + } +} /* validate_composite() */ + + + +/* + * remove_option() - make sure the named option does not exist in any + * of the possible option lists: + * + * Options related to drivers can be present in the Screen, Device and + * Monitor sections and the Display subsections. The order of + * precedence is Display, Screen, Monitor, Device. + */ + +static void remove_option(XConfigScreenPtr screen, const char *name) +{ + XConfigDisplayPtr display; + + if (!screen) return; + + if (screen->device) { + xconfigRemoveNamedOption(&screen->device->options, name, NULL); + } + if (screen->monitor) { + xconfigRemoveNamedOption(&screen->monitor->options, name, NULL); + } + xconfigRemoveNamedOption(&screen->options, name, NULL); + + for (display = screen->displays; display; display = display->next) { + xconfigRemoveNamedOption(&display->options, name, NULL); + } +} /* remove_option() */ + + + +/* + * get_screen_option() - get the option structure with the specified + * name, searching all the option lists associated with this screen + */ + +static XConfigOptionPtr get_screen_option(XConfigScreenPtr screen, + const char *name) +{ + XConfigDisplayPtr display; + XConfigOptionPtr opt; + + if (!screen) return NULL; + + if (screen->device) { + opt = xconfigFindOption(screen->device->options, name); + if (opt) return opt; + } + if (screen->monitor) { + opt = xconfigFindOption(screen->monitor->options, name); + if (opt) return opt; + } + + opt = xconfigFindOption(screen->options, name); + if (opt) return opt; + + for (display = screen->displays; display; display = display->next) { + opt = xconfigFindOption(display->options, name); + if (opt) return opt; + } + + return NULL; + +} /* get_screen_option() */ + + + +/* + * set_option_value() - set the given option to the specified value + */ + +static void set_option_value(XConfigScreenPtr screen, + const char *name, const char *val) +{ + /* first, remove the option to make sure it doesn't exist + elsewhere */ + + remove_option(screen, name); + + /* then, add the option to the screen's option list */ + + xconfigAddNewOption(&screen->options, name, val); + +} /* set_option_value() */ + + + +/* + * find_metamode_offset() - find the first metamode offset in + * 'string'; returns a pointer to the start of the offset + * specification and assigns 'end' (if non-NULL) to the first character + * beyond the offset specification. + */ + +static char *find_metamode_offset(char *string, char **end) +{ + enum { + StateBeforeOffset, + StateInFirstPlus, + StateInFirstNumber, + StateInSecondPlus, + StateInSecondNumber + } state = StateBeforeOffset; + + char *s, *start = NULL, c; + + for (s = string; s && *s; s++) { + c = *s; + switch (state) { + + case StateBeforeOffset: + if ((c == '-') || (c == '+')) { + start = s; + state = StateInFirstPlus; + } + break; + + case StateInFirstPlus: + if (isspace(c)) state = StateInFirstPlus; + else if (isdigit(c)) state = StateInFirstNumber; + else state = StateBeforeOffset; + break; + + case StateInFirstNumber: + if (isdigit(c) || isspace(c)) state = StateInFirstNumber; + else if ((c == '-') || (c == '+')) state = StateInSecondPlus; + else state = StateBeforeOffset; + break; + + case StateInSecondPlus: + if (isspace(c)) state = StateInSecondPlus; + else if (isdigit(c)) state = StateInSecondNumber; + else state = StateBeforeOffset; + break; + + case StateInSecondNumber: + if (isdigit(c)) state = StateInSecondNumber; + else goto done; + break; + } + } + + done: + if (state == StateInSecondNumber) { + if (end) *end = s; + return start; + } + + return NULL; + +} /* find_metamode_offset() */ + + + +/* + * remove_metamode_offsets() - remove any offset specifications from + * the MetaMode option for this screen; if we find any offsets, return + * TRUE and assign old_metamodes and new_metamodes to copies of the + * MetaModes string before and after removing the offsets. If no + * offsets appear in the MetaModes string, return FALSE. + */ + +static int remove_metamode_offsets(XConfigScreenPtr screen, + char **old_metamodes, char **new_metamodes) +{ + char *start, *end = NULL; + char *new_string; + char *n, *o, *tmp; + + XConfigOptionPtr opt = get_screen_option(screen, "MetaModes"); + + /* return if no MetaModes option */ + + if (!opt || !opt->val) return FALSE; + + /* return if no explicit offsets in the MetaModes option */ + + if (!find_metamode_offset(opt->val, NULL)) return FALSE; + + if (old_metamodes) *old_metamodes = nvstrdup(opt->val); + + /* + * if we get this far, there are offsets in the MetaModes string; + * build a new string without the offsets + */ + + new_string = nvstrdup(opt->val); + + o = start = opt->val; + n = new_string; + + while (1) { + + tmp = find_metamode_offset(start, &end); + + if (tmp) *tmp = '\0'; + + while (*o) *n++ = *o++; + + *n = '\0'; + + if (!tmp) break; + + o = start = end; + } + + nvfree(opt->val); + + opt->val = new_string; + + if (new_metamodes) *new_metamodes = nvstrdup(opt->val); + + return TRUE; + +} /* remove_metamode_offsets() */ + + + +/* + * update_display_options() - update the Display SubSection options + */ + +static void update_display_options(Options *op, XConfigScreenPtr screen) +{ + XConfigDisplayPtr display; + int i; + + /* update the mode list, based on what we have on the commandline */ + + for (display = screen->displays; display; display = display->next) { + + /* + * if virtual.[xy] are less than 0, then clear the virtual + * screen size; if they are greater than 0, assign the virtual + * screen size; if they are 0, leave the virtual screen size + * alone + */ + + if ((op->virtual.x < 0) || (op->virtual.y < 0)) { + display->virtualX = display->virtualY = 0; + } else if (op->virtual.x || op->virtual.y) { + display->virtualX = op->virtual.x; + display->virtualY = op->virtual.y; + } + + for (i = 0; i < op->remove_modes.n; i++) { + xconfigRemoveMode(&display->modes, op->remove_modes.t[i]); + } + for (i = 0; i < op->add_modes.n; i++) { + xconfigAddMode(&display->modes, op->add_modes.t[i]); + } + if (op->add_modes_list.n) { + int mode_list_size = op->add_modes_list.n; + + xconfigFreeModeList(&display->modes); + display->modes = NULL; + + /* + * xconfigAddMode() prepends, rather than appends, so add the + * modes in reverse order + */ + + for (i = 0; i < op->add_modes_list.n; i++) { + xconfigAddMode(&display->modes, + op->add_modes_list.t[mode_list_size-i-1]); + } + } + + /* XXX should we sort the mode list? */ + + /* + * XXX should we update the mode list with what we can get + * through libnvidia-cfg? + */ + } + +} /* update_display_options() */ + + + +/* + * update_options() - update the X Config options, based on the + * command line arguments. + */ + +void update_options(Options *op, XConfigScreenPtr screen) +{ + int i; + const NvidiaXConfigOption *o; + char *val; + char scratch[8]; + + /* update any boolean options specified on the commandline */ + + for (i = 0; i < XCONFIG_BOOL_OPTION_COUNT; i++) { + if (GET_BOOL_OPTION(op->boolean_options, i)) { + + /* + * SEPARATE_X_SCREENS_BOOL_OPTION, XINERAMA_BOOL_OPTION, + * COMPOSITE_BOOL_OPTION, PRESERVE_BUSID_BOOL_OPTION, + * and ENABLE_EXTERNAL_GPU_BOOL_OPTION are handled separately + */ + + if (i == SEPARATE_X_SCREENS_BOOL_OPTION) continue; + if (i == XINERAMA_BOOL_OPTION) continue; + if (i == COMPOSITE_BOOL_OPTION) continue; + if (i == PRESERVE_BUSID_BOOL_OPTION) continue; + if (i == ENABLE_PRIME_OPTION) continue; + if (i == ENABLE_EXTERNAL_GPU_BOOL_OPTION) continue; + + o = get_option(i); + + if (!o) { + nv_error_msg("Unrecognized X Config option %d", i); + continue; + } + + if (GET_BOOL_OPTION(op->boolean_option_values, i)) { + val = o->invert ? "False" : "True"; + } else { + val = o->invert ? "True" : "False"; + } + + set_option_value(screen, o->name, val); + nv_info_msg(NULL, "Option \"%s\" \"%s\" added to Screen \"%s\".", + o->name, val, screen->identifier); + } + } + + /* update the Display SubSection options */ + + update_display_options(op, screen); + + /* add the transparent index option */ + + if (op->transparent_index != -1) { + remove_option(screen, "transparentindex"); + if (op->transparent_index != -2) { + snprintf(scratch, 8, "%d", op->transparent_index); + set_option_value(screen, "TransparentIndex", scratch); + } + } + + /* add the stereo option */ + + if (op->stereo != -1) { + remove_option(screen, "stereo"); + if (op->stereo != -2) { + snprintf(scratch, 8, "%d", op->stereo); + set_option_value(screen, "Stereo", scratch); + } + } + + /* add the MultiGPU option */ + + if (op->multigpu) { + remove_option(screen, "MultiGPU"); + if (op->multigpu != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "MultiGPU", op->multigpu); + } + } + + /* add the SLI option */ + + if (op->sli) { + remove_option(screen, "SLI"); + if (op->sli != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "SLI", op->sli); + } + } + + /* add the metamodes option */ + + if (op->metamodes_str) { + remove_option(screen, "MetaModes"); + if (op->metamodes_str != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "MetaModes", op->metamodes_str); + } + } + + /* add acpid socket path option*/ + + if (op->acpid_socket_path) { + remove_option(screen, "AcpidSocketPath"); + if (op->acpid_socket_path != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "AcpidSocketPath", op->acpid_socket_path); + } + } + + /* add the nvidia xinerama info order option */ + + if (op->nvidia_xinerama_info_order) { + remove_option(screen, "nvidiaXineramaInfoOrder"); + if (op->nvidia_xinerama_info_order != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "nvidiaXineramaInfoOrder", + op->nvidia_xinerama_info_order); + } + } + + /* add the metamode orientation option */ + + if (op->metamode_orientation) { + remove_option(screen, "MetaModeOrientation"); + if (op->metamode_orientation != NV_DISABLE_STRING_OPTION) { + char *old_metamodes, *new_metamodes; + set_option_value(screen, "MetaModeOrientation", + op->metamode_orientation); + if (remove_metamode_offsets(screen, + &old_metamodes, &new_metamodes)) { + nv_warning_msg("The MetaModes option contained explicit offsets, " + "which would have overridden the specified " + "MetaModeOrientation; in order to honor the " + "requested MetaModeOrientation, the explicit offsets " + "have been removed from the MetaModes option.\n\n" + "Old MetaModes option: \"%s\"\n" + "New MetaModes option: \"%s\".", + old_metamodes, new_metamodes); + nvfree(old_metamodes); + nvfree(new_metamodes); + } + } + } + + /* add the UseDisplayDevice option */ + + if (op->use_display_device) { + remove_option(screen, "UseDisplayDevice"); + if (op->use_display_device != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "UseDisplayDevice", + op->use_display_device); + } + } + + /* add the CustomEDID option */ + + if (op->custom_edid) { + remove_option(screen, "CustomEDID"); + if (op->custom_edid != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "CustomEDID", op->custom_edid); + } + } + + /* add the TVStandard option */ + + if (op->tv_standard) { + remove_option(screen, "TVStandard"); + if (op->tv_standard != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "TVStandard", op->tv_standard); + } + } + + /* add the TVOutFormat option */ + + if (op->tv_out_format) { + remove_option(screen, "TVOutFormat"); + if (op->tv_out_format != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "TVOutFormat", op->tv_out_format); + } + } + + /* add the Coolbits option */ + + if (op->cool_bits != -1) { + remove_option(screen, "Coolbits"); + if (op->cool_bits != -2) { + snprintf(scratch, 8, "%d", op->cool_bits); + set_option_value(screen, "Coolbits", scratch); + } + } + + /* add the ConnectedMonitor option */ + + if (op->connected_monitor) { + remove_option(screen, "ConnectedMonitor"); + if (op->connected_monitor != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "ConnectedMonitor", op->connected_monitor); + } + } + + if (op->registry_dwords) { + remove_option(screen, "RegistryDwords"); + if (op->registry_dwords != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "RegistryDwords", op->registry_dwords); + } + } + + /* add the ColorSpace option */ + + if (op->color_space) { + remove_option(screen, "ColorSpace"); + if (op->color_space != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "ColorSpace", op->color_space); + } + } + + if (op->color_range) { + remove_option(screen, "ColorRange"); + if (op->color_range != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "ColorRange", op->color_range); + } + } + + /* add the flatpanel properties option */ + + if (op->flatpanel_properties) { + remove_option(screen, "FlatPanelProperties"); + if (op->flatpanel_properties != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "FlatPanelProperties", + op->flatpanel_properties); + } + } + + /* add the 3DVisionUSBPath option */ + if (op->nvidia_3dvision_usb_path) { + remove_option(screen, "3DVisionUSBPath"); + if (op->nvidia_3dvision_usb_path != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "3DVisionUSBPath", op->nvidia_3dvision_usb_path); + } + } + + /* add the 3DVisionProConfigFile option */ + if (op->nvidia_3dvisionpro_config_file) { + remove_option(screen, "3DVisionProConfigFile"); + if (op->nvidia_3dvisionpro_config_file != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "3DVisionProConfigFile", op->nvidia_3dvisionpro_config_file); + } + } + + /* add the 3DVisionDisplayType option */ + + if (op->nvidia_3dvision_display_type != -1) { + remove_option(screen, "3DVisionDisplayType"); + if (op->nvidia_3dvision_display_type != -2) { + snprintf(scratch, 8, "%d", op->nvidia_3dvision_display_type); + set_option_value(screen, "3DVisionDisplayType", scratch); + } + } + + /* add the ForceCompositionPipeline option */ + + if (op->force_composition_pipeline) { + remove_option(screen, "ForceCompositionPipeline"); + if (op->force_composition_pipeline != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "ForceCompositionPipeline", + op->force_composition_pipeline); + } + } + + /* add the ForceFullCompositionPipeline option */ + + if (op->force_full_composition_pipeline) { + remove_option(screen, "ForceFullCompositionPipeline"); + if (op->force_full_composition_pipeline != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "ForceFullCompositionPipeline", + op->force_full_composition_pipeline); + } + } + + /* add the AllowHMD option */ + + if (op->allow_hmd) { + remove_option(screen, "AllowHMD"); + if (op->allow_hmd != NV_DISABLE_STRING_OPTION) { + set_option_value(screen, "AllowHMD", op->allow_hmd); + } + } + +} /* update_options() */ diff --git a/nvidia-xconfig-540.3.0/query_gpu_info.c b/nvidia-xconfig-540.3.0/query_gpu_info.c new file mode 100644 index 0000000..2b753c6 --- /dev/null +++ b/nvidia-xconfig-540.3.0/query_gpu_info.c @@ -0,0 +1,226 @@ +/* + * nvidia-xconfig: A tool for manipulating X config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2006 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * query_gpu_info.c + */ + +#include "nvidia-xconfig.h" +#include "msg.h" +#include + +static char *display_device_mask_to_display_device_name(unsigned int mask); + + + +/* + * query_gpu_info() - query information about the GPU, and print it + * out + */ + +int query_gpu_info(Options *op) +{ + DevicesPtr pDevices; + DisplayDevicePtr pDisplayDevice; + int i, j; + char *name, *busid; + + /* query the GPU information */ + + pDevices = find_devices(op); + + if (!pDevices) { + nv_error_msg("Unable to query GPU information"); + return FALSE; + } + + /* print the GPU information */ + + nv_info_msg(NULL, "Number of GPUs: %d", pDevices->nDevices); + + for (i = 0; i < pDevices->nDevices; i++) { + + nv_info_msg(NULL, ""); + nv_info_msg(NULL, "GPU #%d:", i); + nv_info_msg(TAB, "Name : %s", pDevices->devices[i].name); + nv_info_msg(TAB, "UUID : %s", pDevices->devices[i].uuid); + + busid = nv_format_busid(op, i); + nv_info_msg(TAB, "PCI BusID : %s", busid); + nvfree(busid); + + nv_info_msg(NULL, ""); + nv_info_msg(TAB, "Number of Display Devices: %d", + pDevices->devices[i].nDisplayDevices); + nv_info_msg(NULL, ""); + + for (j = 0; j < pDevices->devices[i].nDisplayDevices; j++) { + + pDisplayDevice = &pDevices->devices[i].displayDevices[j]; + + name = display_device_mask_to_display_device_name + (pDisplayDevice->mask); + + if (!name) name = nvstrdup("Unknown"); + + nv_info_msg(TAB, "Display Device %d (%s):", j, name); + + nvfree(name); + + /* + * convenience macro to first check that the value is + * non-zero + */ + + #define PRT(_fmt, _val) \ + if (_val) { \ + nv_info_msg(BIGTAB, (_fmt), (_val)); \ + } + + if (pDisplayDevice->info_valid) { + + PRT("EDID Name : %s", + pDisplayDevice->info.monitor_name); + + PRT("Minimum HorizSync : %.3f kHz", + pDisplayDevice->info.min_horiz_sync/1000.0); + + PRT("Maximum HorizSync : %.3f kHz", + pDisplayDevice->info.max_horiz_sync/1000.0); + + PRT("Minimum VertRefresh : %d Hz", + pDisplayDevice->info.min_vert_refresh); + + PRT("Maximum VertRefresh : %d Hz", + pDisplayDevice->info.max_vert_refresh); + + PRT("Maximum PixelClock : %.3f MHz", + pDisplayDevice->info.max_pixel_clock/1000.0); + + PRT("Maximum Width : %d pixels", + pDisplayDevice->info.max_xres); + + PRT("Maximum Height : %d pixels", + pDisplayDevice->info.max_yres); + + PRT("Preferred Width : %d pixels", + pDisplayDevice->info.preferred_xres); + + PRT("Preferred Height : %d pixels", + pDisplayDevice->info.preferred_yres); + + PRT("Preferred VertRefresh : %d Hz", + pDisplayDevice->info.preferred_refresh); + + PRT("Physical Width : %d mm", + pDisplayDevice->info.physical_width); + + PRT("Physical Height : %d mm", + pDisplayDevice->info.physical_height); + + } else { + nv_info_msg(BIGTAB, "No EDID information available."); + } + + nv_info_msg(NULL, ""); + } + } + + free_devices(pDevices); + + return TRUE; + +} /* query_gpu_info() */ + + + + +/* + * diaplay_mask/display_name conversions: the NV-CONTROL X extension + * identifies a display device by a bit in a display device mask. The + * below function translates from a display mask to a string + * describing the display devices. + */ + +#define BITSHIFT_CRT 0 +#define BITSHIFT_TV 8 +#define BITSHIFT_DFP 16 + +#define BITMASK_ALL_CRT (0xff << BITSHIFT_CRT) +#define BITMASK_ALL_TV (0xff << BITSHIFT_TV) +#define BITMASK_ALL_DFP (0xff << BITSHIFT_DFP) + +/* + * display_device_mask_to_display_name() - construct a string + * describing the given display device mask. + */ + +#define DISPLAY_DEVICE_STRING_LEN 256 + +static char *display_device_mask_to_display_device_name(unsigned int mask) +{ + char *s; + int first = TRUE; + unsigned int devcnt, devmask; + char *display_device_name_string; + + display_device_name_string = nvalloc(DISPLAY_DEVICE_STRING_LEN); + + s = display_device_name_string; + + devmask = 1 << BITSHIFT_CRT; + devcnt = 0; + while (devmask & BITMASK_ALL_CRT) { + if (devmask & mask) { + if (first) first = FALSE; + else s += sprintf(s, ", "); + s += sprintf(s, "CRT-%X", devcnt); + } + devmask <<= 1; + devcnt++; + } + + devmask = 1 << BITSHIFT_DFP; + devcnt = 0; + while (devmask & BITMASK_ALL_DFP) { + if (devmask & mask) { + if (first) first = FALSE; + else s += sprintf(s, ", "); + s += sprintf(s, "DFP-%X", devcnt); + } + devmask <<= 1; + devcnt++; + } + + devmask = 1 << BITSHIFT_TV; + devcnt = 0; + while (devmask & BITMASK_ALL_TV) { + if (devmask & mask) { + if (first) first = FALSE; + else s += sprintf(s, ", "); + s += sprintf(s, "TV-%X", devcnt); + } + devmask <<= 1; + devcnt++; + } + + *s = '\0'; + + return (display_device_name_string); + +} /* display_device_mask_to_display_name() */ diff --git a/nvidia-xconfig-540.3.0/tree.c b/nvidia-xconfig-540.3.0/tree.c new file mode 100644 index 0000000..9f29b2f --- /dev/null +++ b/nvidia-xconfig-540.3.0/tree.c @@ -0,0 +1,355 @@ +/* + * nvidia-xconfig: A tool for manipulating XConfig files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2004 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * tree.c - this source file contains routines for printing an + * XConfig in a tree format, rooted at the ServerLayout section. + * + * Note that the tree is just printed to stdout (not through an + * ncurses ui) so we can just call printf directly here. + * + * TODO: there are many fields that we are not yet printing + */ + + +#include + +#include "nvidia-xconfig.h" + + + +/* + * print_options() + */ + +static void print_options(XConfigOptionPtr options, int indents) +{ + XConfigOptionPtr opt; + int i; + + for (opt = options; opt; opt = opt->next) { + printf(" |"); + for (i = 1; i < indents; i++) printf(" |"); + printf("--> Option \"%s\"", opt->name); + if (opt->val) printf(" \"%s\"", opt->val); + printf("\n"); + } +} /* print_options() */ + + + +/* + * print_range() + */ + +static void print_range(parser_range* range, int n) +{ + int i; + for (i = 0; i < n; i++) { + if (i > 0) printf(", "); + printf("%.1f-%.1f", range[i].lo, range[i].hi); + } + printf("\n"); + +} /* print_range() */ + + + +/* + * print_monitor() + */ + +static void print_monitor(XConfigMonitorPtr monitor) +{ + XConfigModeLinePtr modeline; + + printf(" | |--> Monitor \"%s\"\n", monitor->identifier); + printf(" | | |\n"); + + if (monitor->vendor) { + printf(" | | |--> VendorName \"%s\"\n", + monitor->vendor); + } + + if (monitor->modelname) { + printf(" | | |--> ModelName \"%s\"\n", + monitor->modelname); + } + + printf(" | | |--> HorizSync "); + print_range(monitor->hsync, monitor->n_hsync); + + printf(" | | |--> VertRefresh "); + print_range(monitor->vrefresh, monitor->n_vrefresh); + + for (modeline = monitor->modelines; modeline; modeline = modeline->next) { + printf(" | | |--> Modeline \"%s\" ...\n", + modeline->identifier); + } + + print_options(monitor->options, 3); + + printf(" | |\n"); + +} /* print_monitor() */ + + + +/* + * print_device() + */ + +static void print_device(XConfigDevicePtr device) +{ + printf(" | |--> Device \"%s\"\n", device->identifier); + + if (device->driver) { + printf(" | | |--> Driver \"%s\"\n", + device->driver); + } + if (device->vendor) { + printf(" | | |--> VendorName \"%s\"\n", + device->vendor); + } + if (device->board) { + printf(" | | |--> BoardName \"%s\"\n", + device->board); + } + if (device->busid) { + printf(" | | |--> BusID \"%s\"\n", + device->busid); + } + if (device->screen >= 0) { + printf(" | | |--> Screen \"%d\"\n", + device->screen); + } + + print_options(device->options, 3); + + printf(" | |\n"); + +} /* print_device() */ + + + +/* + * print_modes() + */ + +static void print_modes(XConfigScreenPtr screen) +{ + XConfigDisplayPtr display; + XConfigModePtr mode; + int printedSomething = 0; + + for (display = screen->displays; display; display = display->next) { + if (display->depth == screen->defaultdepth) { + for (mode = display->modes; mode; mode = mode->next) { + if (!printedSomething) { + printf(" | |--> Modes"); + } + printf(" \"%s\"", mode->mode_name); + printedSomething = 1; + } + break; + } + } + + if (printedSomething) { + printf("\n"); + } + +} /* print_modes() */ + + + +/* + * print_virtual() + */ + +static void print_virtual(XConfigScreenPtr screen) +{ + XConfigDisplayPtr display; + + for (display = screen->displays; display; display = display->next) { + if (display->depth == screen->defaultdepth) { + if (display->virtualX || display->virtualY) { + printf(" | |--> Virtual %d %d\n", + display->virtualX, display->virtualY); + } + break; + } + } + +} /* print_virtual() */ + + + +/* + * print_screen() + */ + +static void print_screen(XConfigScreenPtr screen) +{ + printf(" |--> Screen \"%s\"\n", screen->identifier); + printf(" | |\n"); + print_monitor(screen->monitor); + + print_device(screen->device); + + print_options(screen->options, 2); + + printf(" | |--> DefaultColorDepth %d\n", + screen->defaultdepth); + print_modes(screen); + print_virtual(screen); + + printf(" |\n"); + +} /* print_screen() */ + + + +/* + * print_input() + */ + +static void print_input(XConfigInputrefPtr inputRef) +{ + XConfigInputPtr input = inputRef->input; + + printf(" |--> InputDevice \"%s\"\n", input->identifier); + printf(" | |\n"); + printf(" | |--> Driver \"%s\"\n", input->driver); + + print_options(input->options, 2); + print_options(inputRef->options, 2); + + printf(" |\n"); + +} /* print_input() */ + + + +/* + * print_layout() + */ + +static void print_layout(XConfigLayoutPtr layout) +{ + XConfigAdjacencyPtr adj; + XConfigInputrefPtr input; + + printf("\n"); + printf(" ServerLayout \"%s\"\n", layout->identifier); + printf(" |\n"); + + for (adj = layout->adjacencies; adj; adj = adj->next) { + print_screen(adj->screen); + } + + for (input = layout->inputs; input; input = input->next) { + print_input(input); + } + + print_options(layout->options, 1); + +} /* print_layout() */ + + + +/* + * print_server_flags() + */ + +static void print_server_flags(XConfigPtr config) +{ + if (!config->flags || !config->flags->options) return; + + printf("\n"); + printf(" ServerFlags\n"); + printf(" |\n"); + + print_options(config->flags->options, 1); + + printf("\n"); + +} /* print_server_flags() */ + + + +/* + * print_server_extensions() + */ + +static void print_server_extensions(XConfigPtr config) +{ + if (!config->extensions || !config->extensions->options) return; + + printf("\n"); + printf(" Extensions\n"); + printf(" |\n"); + + print_options(config->extensions->options, 1); + + printf("\n"); + +} /* print_server_extensions() */ + + + +/* + * print_tree() + */ + +int print_tree(Options *op, XConfigPtr config) +{ + XConfigLayoutPtr layout; + + if (!config) { + printf("Unable to locate/open XConfig file.\n"); + return FALSE; + } + + /* + * either use the requested layout or loop over all the layouts in + * the file + */ + + if (op->layout) { + layout = xconfigFindLayout(op->layout, config->layouts); + if (!layout) { + printf("Unable to find layout \"%s\".\n", op->layout); + return FALSE; + } + print_layout(layout); + } else { + for (layout = config->layouts; layout; layout = layout->next) { + print_layout(layout); + } + } + + printf("\n"); + + print_server_flags(config); + + print_server_extensions(config); + + return TRUE; + +} /* print_tree() */ diff --git a/nvidia-xconfig-540.3.0/util.c b/nvidia-xconfig-540.3.0/util.c new file mode 100644 index 0000000..1c56bba --- /dev/null +++ b/nvidia-xconfig-540.3.0/util.c @@ -0,0 +1,204 @@ +/* + * nvidia-xconfig: A tool for manipulating XF86Config files, + * specifically for use by the NVIDIA Linux graphics driver. + * + * Copyright (C) 2004 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * + * util.c + */ + + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "nvidia-xconfig.h" +#include "msg.h" + +Options *__op = NULL; + + +/* + * copy_file() - copy the file specified by srcfile to dstfile, using + * mmap and memcpy. The destination file is created with the + * permissions specified by mode. Roughly based on code presented by + * Richard Stevens, in Advanced Programming in the Unix Environment, + * 12.9. + */ + +int copy_file(const char *srcfile, const char *dstfile, mode_t mode) +{ + int src_fd = -1, dst_fd = -1; + struct stat stat_buf; + char *src, *dst; + int ret = FALSE; + + if ((src_fd = open(srcfile, O_RDONLY)) == -1) { + nv_error_msg("Unable to open '%s' for copying (%s)", + srcfile, strerror (errno)); + goto done; + } + if ((dst_fd = open(dstfile, O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) { + nv_error_msg("Unable to create '%s' for copying (%s)", + dstfile, strerror (errno)); + goto done; + } + if (fstat(src_fd, &stat_buf) == -1) { + nv_error_msg("Unable to determine size of '%s' (%s)", + srcfile, strerror (errno)); + goto done; + } + if (stat_buf.st_size == 0) { + /* src file is empty; silently ignore */ + ret = TRUE; + goto done; + } + if (lseek(dst_fd, stat_buf.st_size - 1, SEEK_SET) == -1) { + nv_error_msg("Unable to set file size for '%s' (%s)", + dstfile, strerror (errno)); + goto done; + } + if (write(dst_fd, "", 1) != 1) { + nv_error_msg("Unable to write file size for '%s' (%s)", + dstfile, strerror (errno)); + goto done; + } + if ((src = mmap(0, stat_buf.st_size, PROT_READ, + MAP_SHARED, src_fd, 0)) == (void *) -1) { + nv_error_msg("Unable to map source file '%s' for " + "copying (%s)", srcfile, strerror (errno)); + goto done; + } + if ((dst = mmap(0, stat_buf.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, dst_fd, 0)) == (void *) -1) { + nv_error_msg("Unable to map destination file '%s' for " + "copying (%s)", dstfile, strerror (errno)); + goto done; + } + + memcpy(dst, src, stat_buf.st_size); + + if (munmap (src, stat_buf.st_size) == -1) { + nv_error_msg("Unable to unmap source file '%s' after " + "copying (%s)", srcfile, strerror (errno)); + goto done; + } + if (munmap (dst, stat_buf.st_size) == -1) { + nv_error_msg("Unable to unmap destination file '%s' after " + "copying (%s)", dstfile, strerror (errno)); + goto done; + } + + ret = TRUE; + + done: + + if (src_fd != -1) close(src_fd); + if (dst_fd != -1) close(dst_fd); + + return ret; + +} /* copy_file() */ + + +/* + * xconfigPrint() - this is the one entry point that a user of the + * XF86Config-Parser library must provide. + */ + +void xconfigPrint(MsgType t, const char *msg) +{ + typedef struct { + MsgType msg_type; + char *prefix; + FILE *stream; + int newline; + } MessageTypeAttributes; + + char *prefix = NULL; + int i, newline = FALSE; + FILE *stream = stdout; + + const MessageTypeAttributes msg_types[] = { + { ParseErrorMsg, "PARSE ERROR: ", stderr, TRUE }, + { ParseWarningMsg, "PARSE WARNING: ", stderr, TRUE }, + { ValidationErrorMsg, "VALIDATION ERROR: ", stderr, TRUE }, + { InternalErrorMsg, "INTERNAL ERROR: ", stderr, TRUE }, + { WriteErrorMsg, "ERROR: ", stderr, TRUE }, + { WarnMsg, "WARNING: ", stderr, TRUE }, + { ErrorMsg, "ERROR: ", stderr, TRUE }, + { DebugMsg, "DEBUG: ", stdout, FALSE }, + { UnknownMsg, NULL, stdout, FALSE }, + }; + + for (i = 0; msg_types[i].msg_type != UnknownMsg; i++) { + if (msg_types[i].msg_type == t) { + prefix = msg_types[i].prefix; + newline = msg_types[i].newline; + stream = msg_types[i].stream; + break; + } + } + + if (newline) nv_info_msg_to_file(stream, NULL, ""); + nv_info_msg_to_file(stream, prefix, "%s", msg); + if (newline) nv_info_msg_to_file(stream, NULL, ""); + +} /* xconfigPrint */ + +/* a round number longer than "PCI:bus@domain:slot:function" */ +#define BUS_ID_STRING_LENGTH 32 + +/* + * nv_format_busid() - returns a newly allocated formatted string with the PCI + * Bus ID of the device with the given index, or NULL on failure. + */ +char *nv_format_busid(Options *op, int index) +{ + char buf[BUS_ID_STRING_LENGTH]; + DevicesPtr pDevices; + NvCfgPciDevice *dev; + + pDevices = find_devices(op); + if (!pDevices || pDevices->nDevices < 1) { + nv_error_msg("Unable to find any GPUs in the system."); + return NULL; + } + if (index >= pDevices->nDevices) { + nv_error_msg("Invalid GPU index value."); + return NULL; + } + + dev = &pDevices->devices[index].dev; + + xconfigFormatPciBusString(buf, sizeof(buf), + dev->domain, dev->bus, dev->slot, 0); + + return nvstrdup(buf); +} diff --git a/nvidia-xconfig-540.3.0/utils.mk b/nvidia-xconfig-540.3.0/utils.mk new file mode 100644 index 0000000..b29a709 --- /dev/null +++ b/nvidia-xconfig-540.3.0/utils.mk @@ -0,0 +1,577 @@ +# +# Copyright (C) 2008 NVIDIA Corporation +# +# 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. +# +# +# utils.mk: common Makefile fragment used by nvidia-xconfig, +# nvidia-installer, and nvidia-settings +# + + + +############################################################################## +# The calling Makefile (when building as part of the NVIDIA graphics +# driver) may export any of the following variables; we assign default +# values if they are not exported by the caller +############################################################################## + +CC ?= gcc +CXX ?= g++ +LD ?= ld +AR ?= ar +# only set these warnings if CFLAGS is unset +CFLAGS ?= -Wall +# always set these -f CFLAGS +CFLAGS += -fno-strict-aliasing -fno-omit-frame-pointer -Wformat=2 +CC_ONLY_CFLAGS ?= -Wstrict-prototypes -Wold-style-definition +CXX_ONLY_CFLAGS ?= +LDFLAGS ?= +BIN_LDFLAGS ?= +EXTRA_CFLAGS ?= + +STACK_USAGE_WARNING ?= +CFLAGS += $(if $(STACK_USAGE_WARNING),-Wstack-usage=$(STACK_USAGE_WARNING)) + +HOST_CC ?= $(CC) +HOST_LD ?= $(LD) +HOST_CFLAGS ?= $(CFLAGS) +HOST_CC_ONLY_CFLAGS ?= +HOST_CXX_ONLY_CFLAGS ?= +HOST_LDFLAGS ?= $(LDFLAGS) +HOST_BIN_LDFLAGS ?= + +# always disable warnings that will break the build +CC_ONLY_CFLAGS += -Wno-format-zero-length +CFLAGS += -Wno-unused-parameter +HOST_CC_ONLY_CFLAGS += -Wno-format-zero-length +HOST_CFLAGS += -Wno-unused-parameter + +# Treat warnings as errors, if requested +WARNINGS_AS_ERRORS ?= +CFLAGS += $(if $(WARNINGS_AS_ERRORS),-Werror) + +DEBUG ?= +DEVELOP ?= + +ifeq ($(DEBUG),1) + STRIP_CMD ?= true + DO_STRIP ?= + CFLAGS += -O0 -g + CFLAGS += -DDEBUG=1 +else + CFLAGS += -O2 +endif + +ifeq ($(DEVELOP),1) + STRIP_CMD ?= true + DO_STRIP ?= + CFLAGS += -DDEVELOP=1 +endif + +CFLAGS += $(EXTRA_CFLAGS) + +STRIP_CMD ?= strip +DO_STRIP ?= 1 + +INSTALL ?= install +INSTALL_BIN_ARGS ?= -m 755 +INSTALL_LIB_ARGS ?= -m 644 +INSTALL_DOC_ARGS ?= -m 644 + +M4 ?= m4 +SED ?= sed +M4 ?= m4 +ECHO ?= echo +PRINTF ?= printf +MKDIR ?= mkdir -p +RM ?= rm -f +TOUCH ?= touch +HARDLINK ?= ln -f +DATE ?= date +GZIP_CMD ?= gzip +CHMOD ?= chmod +OBJCOPY ?= objcopy +XZ ?= xz +WHOAMI ?= whoami + +ifndef HOSTNAME + HOSTNAME = $(shell hostname) +endif + + +NV_AUTO_DEPEND ?= 1 +NV_VERBOSE ?= 0 + +ifndef TARGET_OS + TARGET_OS := $(shell uname) +endif + +ifeq ($(TARGET_OS),Linux) + CFLAGS += -DNV_LINUX +endif + +ifeq ($(TARGET_OS),FreeBSD) + CFLAGS += -DNV_BSD +endif + +ifeq ($(TARGET_OS),SunOS) + CFLAGS += -DNV_SUNOS +endif + +ifndef TARGET_ARCH + TARGET_ARCH := $(shell uname -m) + TARGET_ARCH := $(subst i386,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst i486,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst i586,x86,$(TARGET_ARCH)) + TARGET_ARCH := $(subst i686,x86,$(TARGET_ARCH)) +endif + +ifeq ($(TARGET_ARCH),x86) + CFLAGS += -DNV_X86 -DNV_ARCH_BITS=32 +endif + +ifeq ($(TARGET_ARCH),x86_64) + CFLAGS += -DNV_X86_64 -DNV_ARCH_BITS=64 +endif + +ifeq ($(TARGET_ARCH),armv7l) + CFLAGS += -DNV_ARMV7 -DNV_ARCH_BITS=32 +endif + +ifeq ($(TARGET_ARCH),aarch64) + CFLAGS += -DNV_AARCH64 -DNV_ARCH_BITS=64 +endif + +ifeq ($(TARGET_ARCH),ppc64le) + CFLAGS += -DNV_PPC64LE -DNV_ARCH_BITS=64 +endif + +ifeq ($(TARGET_OS),Linux) + LIBDL_LIBS = -ldl +else + LIBDL_LIBS = +endif + +# This variable controls which floating-point ABI is targeted. For ARM, it +# defaults to "gnueabi" for softfp. Another option is "gnueabihf" for +# hard(fp). This is necessary to pick up the correct rtld_test binary. +# All other architectures default to empty. +ifeq ($(TARGET_ARCH),armv7l) + TARGET_ARCH_ABI ?= gnueabi +endif +TARGET_ARCH_ABI ?= + +ifeq ($(TARGET_ARCH_ABI),gnueabi) + CFLAGS += -DNV_GNUEABI +endif + +ifeq ($(TARGET_ARCH_ABI),gnueabihf) + CFLAGS += -DNV_GNUEABIHF +endif + +OUTPUTDIR ?= _out/$(TARGET_OS)_$(TARGET_ARCH) +OUTPUTDIR_ABSOLUTE ?= $(CURDIR)/$(OUTPUTDIR) + +NV_SEPARATE_DEBUG_INFO ?= +NV_KEEP_UNSTRIPPED_BINARIES ?= + +NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX ?= + +NV_GENERATED_HEADERS ?= + +PCIACCESS_CFLAGS ?= +PCIACCESS_LDFLAGS ?= + +############################################################################## +# This makefile uses the $(eval) builtin function, which was added in +# GNU make 3.80. Check that the current make version recognizes it. +# Idea suggested by "The GNU Make Book" by John Graham-Cumming. +############################################################################## + +_eval_available := +$(eval _eval_available := T) + +ifneq ($(_eval_available),T) + $(error This Makefile requires a GNU Make that supports 'eval'. Please upgrade to GNU make 3.80 or later) +endif + +############################################################################## +# Test passing $(1) to $(CC). If $(CC) succeeds, then echo $(1). +# +# Because this uses $(shell), it is best to use this to assign simply expanded +# variables (e.g., ":="). +# +# Example usage: +# CONDITIONAL_CFLAGS := $(call TEST_CC_ARG, -ffoo) +############################################################################## + +TEST_CC_ARG = \ + $(shell $(CC) -c -x c /dev/null -Werror $(1) -o /dev/null > /dev/null 2>&1 && \ + $(ECHO) $(1)) + + +############################################################################## +# Test if instruction $(1) is understood by the assembler +# Returns "1" if the instruction is understood, else returns empty string. +# +# Example usage: +# ENDBR_SUPPORTED := $(call AS_HAS_INSTR, endbr64) +############################################################################## + +AS_HAS_INSTR = \ + $(shell if ($(ECHO) "$(1)" | $(CC) -c -x assembler - -o /dev/null) >/dev/null 2>&1 ;\ + then $(ECHO) "1"; else $(ECHO) ""; fi) + + +############################################################################## +# define variables used when installing the open source utilities from +# the source tarball +############################################################################## + +PREFIX ?= /usr/local + +BINDIR = $(DESTDIR)$(PREFIX)/bin +LIBDIR = $(DESTDIR)$(PREFIX)/lib +MANDIR = $(DESTDIR)$(PREFIX)/share/man/man1 + + +############################################################################## +# default build rule, so that nothing here in utils.mk accidentally +# gets selected as the default rule +############################################################################## + +default build: all +.PHONY: default build + +############################################################################## +# get the definition of NVIDIA_VERSION from version.mk +# +# version.mk may be in one of two places: either in $(OUTPUTDIR) when +# building as part of the NVIDIA driver build, or directly in the +# source directory when building from the source tarball +# +# Throw an error if one of these two places did not define NVIDIA_VERSION. +############################################################################## + +VERSION_MK_DIR ?= . +VERSION_MK := $(wildcard $(OUTPUTDIR)/version.mk $(VERSION_MK_DIR)/version.mk ) +include $(VERSION_MK) + +ifndef NVIDIA_VERSION +$(error NVIDIA_VERSION undefined) +endif + +############################################################################## +# NV_GET_SOURCE_TYPE: if the source file $(1) should be compiled as C, this +# evalutes to "CC"; if the source file $(1) should be compiled as C++, this +# evalutes to "CXX". +############################################################################## + +NV_GET_SOURCE_TYPE = $(strip \ + $(if $(filter %.c, $(1)),CC, \ + $(if $(filter %.cpp, $(1)),CXX, \ + $(error Unrecognized source $(1))))) + + +############################################################################## +# Several of the functions below take an argument that indicates if +# the expression is for the target platform (the system the built +# program is going to run on) or the host platform (the system +# performing the build). The argument is either "HOST" or "TARGET" +# and needs to be converted: +# +# "HOST" -> "HOST_" +# "TARGET" -> "" +############################################################################## + +host_target = $(patsubst HOST,HOST_,$(patsubst TARGET,,$(1))) + + +############################################################################## +# To generate the dependency files: +# +# - Use the compiler's "-MMD" option to generate output of the form +# "foo.o : foo.c foo.h bar.h". +# +# - Also, "-MMD" will cause the compiler to name the target as if it were in the +# current directory ("foo.o: "); use -MT to rename the target in the output +# directory ("_out/Linux_x86/foo.o: ") so that the target actually applies to +# the object files produced in the build. +# +# - Use -MP to generate a phony target for each of those prerequisites (except +# the source file being compiled). E.g., +# "foo.o : foo.c foo.h bar.h +# foo.h: +# bar.h:" +# so that the makefile can handle incremental builds after a prerequisite has +# been deleted from source control. +# +# - Use sed to remove the source file from the list of prerequisties in the +# above, so that the makefile can handle increment builds after the source has +# moved from one directory to another. The DEFINE_OBJECT_RULE macro spells +# out the obj: src dependency, so we don't require it here. +############################################################################## + +ifeq ($(NV_AUTO_DEPEND),1) + AUTO_DEP_SUFFIX = -MMD -MF $$(@:.o=.d.to_be_processed) -MP -MT $$@ && \ + $$(SED) -e "1,3s| $$< | |" < $$(@:.o=.d.to_be_processed) > $$(@:.o=.d) +else + AUTO_DEP_SUFFIX = +endif + + +############################################################################## +# echo minimal compile information in the non-NV_VERBOSE case +# +# NV_MODULE_LOGGING_NAME can be set to prepend quiet build output with a +# label of which build component is being built +############################################################################## + +NV_MODULE_LOGGING_NAME ?= + +ifeq ($(NV_VERBOSE),0) + at_if_quiet := @ + quiet_cmd_no_at = $(PRINTF) \ + " $(if $(NV_MODULE_LOGGING_NAME),[ %-17.17s ],%s) $(quiet_$(1))\n" \ + "$(NV_MODULE_LOGGING_NAME)" && $($(1)) + quiet_cmd = @$(quiet_cmd_no_at) +else + at_if_quiet := + quiet_cmd_no_at = $($(1)) + quiet_cmd = $($(1)) +endif + +# define LINK and HOST_LINK to be the same as CC; this is so that, +# even though we use CC to link programs, we can have a different +# quiet rule that uses '$@' as it's arg, rather than '$<' +LINK = $(CC) +HOST_LINK = $(HOST_CC) + +# strip NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX from the target string +define_quiet_cmd = $(1) $(patsubst $(NV_QUIET_COMMAND_REMOVED_TARGET_PREFIX)/%,%,$(2)) + +# define the quiet commands: +quiet_CC = $(call define_quiet_cmd,CC ,$<) +quiet_CXX = $(call define_quiet_cmd,CXX ,$<) +quiet_HOST_CC = $(call define_quiet_cmd,HOST_CC ,$<) +quiet_HOST_CXX = $(call define_quiet_cmd,HOST_CXX ,$<) +quiet_LINK = $(call define_quiet_cmd,LINK ,$@) +quiet_HOST_LINK = $(call define_quiet_cmd,HOST_LINK ,$@) +quiet_M4 = $(call define_quiet_cmd,M4 ,$<) +quiet_STRIP_CMD = $(call define_quiet_cmd,STRIP ,$@) +quiet_HARDLINK = $(call define_quiet_cmd,HARDLINK ,$@) +quiet_LD = $(call define_quiet_cmd,LD ,$@) +quiet_OBJCOPY = $(call define_quiet_cmd,OBJCOPY ,$@) +quiet_AR = $(call define_quiet_cmd,AR ,$@) +quiet_XZ = $(call define_quiet_cmd,XZ ,$@) + +############################################################################## +# Tell gmake to delete the target of a rule if it has changed and its +# commands exit with a nonzero exit status. +############################################################################## +.DELETE_ON_ERROR: + + +############################################################################## +# function to generate a list of object files from their corresponding +# source files using the specified path. The _WITH_DIR variant takes an +# output path as the second argument while the BUILD_OBJECT_LIST defaults +# to using the value of OUTPUTDIR as the output path. example usage: +# +# OBJS = $(call BUILD_OBJECT_LIST_WITH_DIR,$(SRC),$(DIR)) +############################################################################## + +BUILD_OBJECT_LIST_WITH_DIR = \ + $(addprefix $(2)/,$(notdir $(addsuffix .o,$(basename $(1))))) + +BUILD_OBJECT_LIST = \ + $(call BUILD_OBJECT_LIST_WITH_DIR,$(1),$(OUTPUTDIR)) + +$(call BUILD_OBJECT_LIST,nvpci-utils.c): CFLAGS += $(PCIACCESS_CFLAGS) + +############################################################################## +# function to generate a list of dependency files from their +# corresponding source files using the specified path. The _WITH_DIR +# variant takes an output path as the second argument while the +# BUILD_DEPENDENCY_LIST default to using the value of OUTPUTDIR as the +# output path. example usage: +# +# DEPS = $(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(SRC),$(DIR)) +############################################################################## + +BUILD_DEPENDENCY_LIST_WITH_DIR = \ + $(addprefix $(2)/,$(notdir $(addsuffix .d,$(basename $(1))))) + +BUILD_DEPENDENCY_LIST = \ + $(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(1),$(OUTPUTDIR)) + + +############################################################################## +# functions to define a rule to build an object file; the first +# argument for all functions is whether the rule is for the target or +# host platform ("HOST" or "TARGET"), the second argument for all +# functions is the source file to compile. +# +# An order-only dependency is added on any generated header files listed in +# $(NV_GENERATED_HEADERS), to ensure they're present before invoking the +# compiler. For incremental builds where the object file already exists, a +# real (not order-only) dependency will be created by automatic dependency +# tracking if needed. +# +# The _WITH_OBJECT_NAME and _WITH_DIR function name suffixes describe +# the third and possibly fourth arguments based on order. The +# _WITH_OBJECT_NAME argument is the object filename to produce while +# the _WITH_DIR argument is the destination path for the object file. +# +# Example usage: +# +# $(eval $(call DEFINE_OBJECT_RULE,TARGET,foo.c)) +# +# Note this also attempts to include the dependency file for this +# source file. +# +# The DEFINE_OBJECT_RULE is functionally equivalent to +# DEFINE_OBJECT_RULE_WITH_OBJECT_NAME, but infers the object file name +# from the source file name (this is normally what you want). +# +# Arguments: +# $(1) : HOST or TARGET +# $(2) : source file +# $(3) : object file +# $(4) : directory +############################################################################## + +define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME_WITH_DIR + $(3): NV_SOURCE_TYPE = $$(call NV_GET_SOURCE_TYPE,$(2)) + + # obj: {HOST_,}CFLAGS += $$({HOST_,}{CC,CXX}_ONLY_CFLAGS) + $(3): $$(call host_target,$(1))CFLAGS += \ + $$($(call host_target,$(1))$$(NV_SOURCE_TYPE)_ONLY_CFLAGS) + + $(3): $(2) | $$(NV_GENERATED_HEADERS) + @$(MKDIR) $(4) + $$(call quiet_cmd,$(call host_target,$(1))$$(NV_SOURCE_TYPE)) \ + $$($(call host_target,$(1))CFLAGS) -c $$< -o $$@ \ + $(AUTO_DEP_SUFFIX) + + -include $$(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(3),$(4)) + + # declare empty rule for generating dependency file; we generate the + # dependency files implicitly when compiling the source file (see + # AUTO_DEP_SUFFIX above), so we don't want gmake to spend time searching + # for an explicit rule to generate the dependency file + $$(call BUILD_DEPENDENCY_LIST_WITH_DIR,$(3),$(4)): ; + +endef + +define DEFINE_OBJECT_RULE_WITH_OBJECT_NAME + $$(eval $$(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME_WITH_DIR,$(1),$(2),\ + $(3),$(OUTPUTDIR))) +endef + +define DEFINE_OBJECT_RULE_WITH_DIR + $$(eval $$(call DEFINE_OBJECT_RULE_WITH_OBJECT_NAME_WITH_DIR,$(1),$(2),\ + $$(call BUILD_OBJECT_LIST_WITH_DIR,$(2),$(3)),$(3))) +endef + +define DEFINE_OBJECT_RULE + $$(eval $$(call DEFINE_OBJECT_RULE_WITH_DIR,$(1),$(2),$(OUTPUTDIR))) +endef + +# This is a function that will generate rules to build +# files with separate debug information, if so requested. +# +# It takes one parameter: (1) Name of unstripped binary +# +# When used, the target for linking should be named (1).unstripped +# +# If separate debug information is requested, it will +# generate a rule to build one from the unstripped binary. +# If requested, it will also retain the unstripped binary. +define DEBUG_INFO_RULES + $(1): $(1).unstripped + ifneq ($(or $(DO_STRIP),$(NV_SEPARATE_DEBUG_INFO)),) + $$(call quiet_cmd,STRIP_CMD) -o $$@ $$< + else + $$(call quiet_cmd,HARDLINK) $$^ $$@ + endif + ifeq ($(NV_SEPARATE_DEBUG_INFO),1) + $(1).debug: $(1).unstripped + $$(call quiet_cmd,STRIP_CMD) --only-keep-debug -o $$@ $$< + $(1): $(1).debug + endif + ifneq ($(NV_KEEP_UNSTRIPPED_BINARIES),1) + .INTERMEDIATE: $(1).unstripped + endif +endef + +############################################################################## +# Define rule for generating a source file containing identification information +# for the build. +# +# $(1) string name +# $(2) module name +# $(3) prerequisite object files +############################################################################## + +NVIDSTRING = $(OUTPUTDIR)/g_nvid_string.c + +ifeq ($(DEBUG),1) + NVIDSTRING_BUILD_TYPE_STRING = Debug Build +else + NVIDSTRING_BUILD_TYPE_STRING = Release Build +endif + +define GENERATE_NVIDSTRING + # g_nvid_string.c depends on all objects except g_nvid_string.o, and version.mk + $(NVIDSTRING): $$(filter-out $$(call BUILD_OBJECT_LIST,$$(NVIDSTRING)), $(3)) $$(VERSION_MK) + $(at_if_quiet)$$(MKDIR) $$(dir $$@) + $(at_if_quiet)$$(ECHO) "const char $(1)[] = \"nvidia id: NVIDIA $$(strip $(2)) for $$(TARGET_ARCH) $$(NVIDIA_VERSION) $$(NVIDSTRING_BUILD_TYPE_STRING) (`$$(WHOAMI)`@$$(HOSTNAME)) `$$(DATE)`\";" > $$@ + $(at_if_quiet)$$(ECHO) "const char *const p$$(strip $(1)) = $(1) + 11;" >> $$@; +endef + + +############################################################################## +# Define rules that can be used for embedding a file into an ELF object that +# contains the raw contents of that file and symbols pointing to the embedded +# data. +# +# Note that objcopy will name the symbols in the resulting object file based on +# the filename specified in $(1). For example, +# +# $(eval $(call $(READ_ONLY_OBJECT_FROM_FILE_RULE),a/b/c)) +# +# will create an object named $(OUTPUTDIR)/c.o with the symbols _binary_c_start, +# _binary_c_end, and _binary_c_size. +# +# Arguments: +# $(1): Path to the file to convert +############################################################################## + +define READ_ONLY_OBJECT_FROM_FILE_RULE + $$(OUTPUTDIR)/$$(notdir $(1)).o: $(1) + $(at_if_quiet)$$(MKDIR) $$(OUTPUTDIR) + $(at_if_quiet)cd $$(dir $(1)); \ + $$(call quiet_cmd_no_at,LD) -r -z noexecstack --format=binary \ + $$(notdir $(1)) -o $$(OUTPUTDIR_ABSOLUTE)/$$(notdir $$@) + $$(call quiet_cmd,OBJCOPY) \ + --rename-section .data=.rodata,contents,alloc,load,data,readonly \ + $$@ +endef diff --git a/nvidia-xconfig-540.3.0/version.mk b/nvidia-xconfig-540.3.0/version.mk new file mode 100644 index 0000000..c00869b --- /dev/null +++ b/nvidia-xconfig-540.3.0/version.mk @@ -0,0 +1,9 @@ +NVIDIA_VERSION = 540.3.0 + +# This file. +VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST)) +$(OUTPUTDIR)/version.h: $(VERSION_MK_FILE) + @$(MKDIR) $(OUTPUTDIR) + @$(ECHO) '#define NVIDIA_VERSION "$(NVIDIA_VERSION)"' > $@ + +NV_GENERATED_HEADERS += $(OUTPUTDIR)/version.h diff --git a/push_info.txt b/push_info.txt new file mode 100644 index 0000000..051d5f1 --- /dev/null +++ b/push_info.txt @@ -0,0 +1 @@ +jetson_36.3