summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2008-02-13 10:26:53 -0800
committerAaron Plattner <aplattner@nvidia.com>2008-02-13 10:26:53 -0800
commit776e01ad78bae30842ca1bc5b9e78ab7c143924f (patch)
treed656daeee6c86a777eb55f301e1ec290d5b13755
parentaedec718b1d6e9487861528dfb310db0b3a53c89 (diff)
-rw-r--r--XF86Config-parser/Makefile3
-rw-r--r--XF86Config-parser/Merge.c712
-rw-r--r--XF86Config-parser/Monitor.c14
-rw-r--r--XF86Config-parser/xf86Parser.h11
-rw-r--r--extract_edids.c1
-rw-r--r--multiple_screens.c18
-rw-r--r--nvgetopt.c11
-rw-r--r--nvgetopt.h13
-rw-r--r--nvidia-cfg.h12
-rw-r--r--nvidia-xconfig.c100
-rw-r--r--nvidia-xconfig.h8
-rw-r--r--option_table.h46
-rw-r--r--options.c42
13 files changed, 980 insertions, 11 deletions
diff --git a/XF86Config-parser/Makefile b/XF86Config-parser/Makefile
index ef973a6..721945d 100644
--- a/XF86Config-parser/Makefile
+++ b/XF86Config-parser/Makefile
@@ -17,7 +17,8 @@ SRC = \
Write.c \
Util.c \
Extensions.c \
- Generate.c
+ Generate.c \
+ Merge.c
OBJS = $(SRC:%.c=%.o)
DEPS = $(SRC:%.c=%.d)
diff --git a/XF86Config-parser/Merge.c b/XF86Config-parser/Merge.c
new file mode 100644
index 0000000..2931934
--- /dev/null
+++ b/XF86Config-parser/Merge.c
@@ -0,0 +1,712 @@
+/*
+ *
+ * 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;
+
+ if (!option || !existing_comments)
+ return;
+
+ len = 32 + strlen(xconfigOptionName(option)) +
+ strlen(xconfigOptionValue(option));
+
+ str = (char *)malloc(len);
+
+ if (str) {
+ snprintf(str, len, "# Removed Option \"%s\" \"%s\"",
+ xconfigOptionName(option),
+ xconfigOptionValue(option));
+ *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
+ *
+ */
+static void xconfigRemoveNamedOption(XConfigOptionPtr *head, char *name,
+ char **comments)
+{
+ XConfigOptionPtr option;
+
+ option = xconfigFindOption(*head, name);
+ if (option) {
+ if (comments) {
+ xconfigAddRemovedOptionComment(comments, option);
+ }
+ *head = xconfigRemoveOption(*head, option);
+ }
+
+} /* xconfigRemoveNamedOption() */
+
+
+
+/*
+ * 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, remove it from the dest
+ * config.
+ *
+ * If the option is in the source config, make sure the dest config
+ * contains the option with the same value as the source config.
+ *
+ * if "comments" is given, a comment will be added to note when
+ * an option has been removed/replaced.
+ *
+ */
+static void xconfigMergeOption(XConfigOptionPtr *dstHead,
+ XConfigOptionPtr *srcHead,
+ const char *name, char **comments)
+{
+ XConfigOptionPtr srcOption = xconfigFindOption(*srcHead, name);
+ XConfigOptionPtr dstOption = xconfigFindOption(*dstHead, name);
+
+ if (!srcOption) {
+ if (dstOption) {
+ *dstHead = xconfigRemoveOption(*dstHead, dstOption);
+ }
+ } else {
+ if (!dstOption || strcmp(xconfigOptionValue(srcOption),
+ xconfigOptionValue(dstOption))) {
+
+ if (dstOption && comments) {
+ xconfigAddRemovedOptionComment(comments, dstOption);
+ }
+ *dstHead = xconfigAddNewOption
+ (*dstHead, xconfigStrdup(name),
+ xconfigStrdup(xconfigOptionValue(srcOption)));
+ }
+ }
+
+} /* 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);
+ dstMonitor->modes_sections = NULL;
+
+} /* 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);
+
+ dstConfig->monitors = (XConfigMonitorPtr)
+ 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);
+
+ dstConfig->devices = (XConfigDevicePtr)
+ 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 || !strcmp(xconfigOptionValue(option),
+ xconfigOptionValue(old))) {
+ xconfigRemoveNamedOption(&(dstScreen->options), name,
+ NULL);
+ } else {
+ xconfigRemoveNamedOption(&(dstScreen->options), name,
+ &(dstScreen->comment));
+ }
+ }
+
+ /* Add the option to the screen->options list */
+
+ dstScreen->options =
+ xconfigAddNewOption(dstScreen->options,
+ xconfigStrdup(name),
+ xconfigStrdup(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;
+ XConfigOptionPtr srcOption;
+ 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 */
+
+ srcOption = srcDisplay->options;
+ while (srcOption) {
+ xconfigMergeOption(&(dstDisplay->options),
+ &(srcDisplay->options),
+ xconfigOptionName(srcOption),
+ NULL);
+ srcOption = srcOption->next;
+ }
+
+ /* Copy modes over */
+
+ lastDstMode = NULL;
+ srcMode = srcDisplay->modes;
+ while (srcMode) {
+
+ /* Copy the mode */
+
+ dstMode = xconfigAddMode(NULL, 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;
+ }
+ }
+
+ 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);
+
+ dstConfig->screens = (XConfigScreenPtr)
+ 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;
+
+ /* 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;
+ }
+
+ return 1;
+
+} /* xconfigMergeLayout() */
+
+
+
+/*
+ * 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 falid */
+ // 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;
+ }
+
+ return 1;
+
+} /* xconfigMergeConfigs() */
diff --git a/XF86Config-parser/Monitor.c b/XF86Config-parser/Monitor.c
index cacc284..e8d8e3c 100644
--- a/XF86Config-parser/Monitor.c
+++ b/XF86Config-parser/Monitor.c
@@ -833,6 +833,20 @@ xconfigFreeModeLineList (XConfigModeLinePtr ptr)
}
}
+void
+xconfigFreeModesLinkList (XConfigModesLinkPtr ptr)
+{
+ XConfigModesLinkPtr prev;
+
+ while (ptr)
+ {
+ TEST_FREE (ptr->modes_name);
+ prev = ptr;
+ ptr = ptr->next;
+ free (prev);
+ }
+}
+
XConfigMonitorPtr
xconfigFindMonitor (const char *ident, XConfigMonitorPtr p)
{
diff --git a/XF86Config-parser/xf86Parser.h b/XF86Config-parser/xf86Parser.h
index 40b8162..7013b9b 100644
--- a/XF86Config-parser/xf86Parser.h
+++ b/XF86Config-parser/xf86Parser.h
@@ -652,6 +652,8 @@ void xconfigFreeVideoPortList(XConfigVideoPortPtr ptr);
void xconfigFreeBuffersList (XConfigBuffersPtr ptr);
void xconfigFreeDRI(XConfigDRIPtr ptr);
void xconfigFreeExtensions(XConfigExtensionsPtr ptr);
+void xconfigFreeModesLinkList(XConfigModesLinkPtr ptr);
+
/*
@@ -734,4 +736,13 @@ void xconfigGeneratePrintPossibleKeyboards(void);
int xconfigCheckCoreInputDevices(GenerateOptions *gop,
XConfigPtr config, XConfigLayoutPtr layout);
+
+/*
+ * X config tools
+ */
+
+int xconfigMergeConfigs(XConfigPtr dstConfig, XConfigPtr srcConfig);
+
+
+
#endif /* _xf86Parser_h_ */
diff --git a/extract_edids.c b/extract_edids.c
index 25a4747..8ae75b2 100644
--- a/extract_edids.c
+++ b/extract_edids.c
@@ -77,6 +77,7 @@
#include <sys/types.h>
#include <pwd.h>
#include <stdarg.h>
+#include <strings.h> /* bzero() */
#include "nvidia-xconfig.h"
diff --git a/multiple_screens.c b/multiple_screens.c
index a8f6acb..d57f4c7 100644
--- a/multiple_screens.c
+++ b/multiple_screens.c
@@ -114,8 +114,10 @@ DevicesPtr find_devices(Options *op)
DisplayDevicePtr pDisplayDevice;
int i, j, n, count = 0;
unsigned int mask, bit;
+ DeviceRec tmpDevice;
NvCfgDeviceHandle handle;
NvCfgDevice *devs = NULL;
+ NvCfgBool is_primary_device;
char *lib_path;
void *lib_handle;
@@ -128,6 +130,8 @@ DevicesPtr find_devices(Options *op)
NvCfgBool (*__getEDID)(NvCfgDeviceHandle handle,
unsigned int display_device,
NvCfgDisplayDeviceInformation *info);
+ NvCfgBool (*__isPrimaryDevice)(NvCfgDeviceHandle handle,
+ NvCfgBool *is_primary_device);
NvCfgBool (*__closeDevice)(NvCfgDeviceHandle handle);
/* dlopen() the nvidia-cfg library */
@@ -157,7 +161,8 @@ DevicesPtr find_devices(Options *op)
dlclose(lib_handle); \
return NULL; \
}
-
+
+ /* required functions */
__GET_FUNC(__getDevices, "nvCfgGetDevices");
__GET_FUNC(__openDevice, "nvCfgOpenDevice");
__GET_FUNC(__getNumCRTCs, "nvCfgGetNumCRTCs");
@@ -165,6 +170,9 @@ DevicesPtr find_devices(Options *op)
__GET_FUNC(__getDisplayDevices, "nvCfgGetDisplayDevices");
__GET_FUNC(__getEDID, "nvCfgGetEDID");
__GET_FUNC(__closeDevice, "nvCfgCloseDevice");
+
+ /* optional functions */
+ __isPrimaryDevice = dlsym(lib_handle, "nvCfgIsPrimaryDevice");
if (__getDevices(&count, &devs) != NVCFG_TRUE) {
return NULL;
@@ -232,6 +240,14 @@ DevicesPtr find_devices(Options *op)
pDevices->devices[i].displayDevices = NULL;
}
+ if ((i != 0) && (__isPrimaryDevice != NULL) &&
+ (__isPrimaryDevice(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));
+ }
+
if (__closeDevice(handle) != NVCFG_TRUE)
goto fail;
}
diff --git a/nvgetopt.c b/nvgetopt.c
index a0dfeea..f09e9b0 100644
--- a/nvgetopt.c
+++ b/nvgetopt.c
@@ -49,7 +49,8 @@
*/
int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
- char **strval, int *boolval, int *intval, int *disable_val)
+ char **strval, int *boolval, int *intval, double *doubleval,
+ int *disable_val)
{
char *c, *a, *arg, *name = NULL, *argument=NULL;
int i, found = NVGETOPT_FALSE, ret = 0, val = NVGETOPT_FALSE;
@@ -239,6 +240,14 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
}
} else if ((o->flags & NVGETOPT_STRING_ARGUMENT) && (strval)) {
*strval = strdup(argument);
+ } else if ((o->flags & NVGETOPT_DOUBLE_ARGUMENT) && (doubleval)) {
+ 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);
diff --git a/nvgetopt.h b/nvgetopt.h
index da29561..387a077 100644
--- a/nvgetopt.h
+++ b/nvgetopt.h
@@ -73,9 +73,17 @@
#define NVGETOPT_ALLOW_DISABLE 0x8
+/*
+ * indicates that the option takes an argument to be interpretted as
+ * an double; on success, nvgetopt will return the parsed double
+ * argument through 'doubleval'.
+ */
+
+#define NVGETOPT_DOUBLE_ARGUMENT 0x10
#define NVGETOPT_HAS_ARGUMENT (NVGETOPT_STRING_ARGUMENT | \
- NVGETOPT_INTEGER_ARGUMENT)
+ NVGETOPT_INTEGER_ARGUMENT | \
+ NVGETOPT_DOUBLE_ARGUMENT)
typedef struct {
const char *name;
@@ -86,6 +94,7 @@ typedef struct {
} NVGetoptOption;
int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
- char **strval, int *boolval, int *intval, int *disable_val);
+ char **strval, int *boolval, int *intval, double *doubleval,
+ int *disable_val);
#endif /* __NVGETOPT_H__ */
diff --git a/nvidia-cfg.h b/nvidia-cfg.h
index 020d947..6069d2a 100644
--- a/nvidia-cfg.h
+++ b/nvidia-cfg.h
@@ -226,4 +226,16 @@ 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);
+
#endif /* __NVIDIA_CFG__ */
diff --git a/nvidia-xconfig.c b/nvidia-xconfig.c
index 3ae1af8..be6a4ff 100644
--- a/nvidia-xconfig.c
+++ b/nvidia-xconfig.c
@@ -236,6 +236,7 @@ Options *parse_commandline(int argc, char *argv[])
int c, boolval;
char *strval;
int intval, disable;
+ double doubleval;
op = (Options *) nvalloc(sizeof(Options));
@@ -243,11 +244,13 @@ Options *parse_commandline(int argc, char *argv[])
op->nvagp = -1;
op->transparent_index = -1;
op->stereo = -1;
+ op->cool_bits = -1;
+ op->tv_over_scan = -1.0;
while (1) {
c = nvgetopt(argc, argv, __options, &strval,
- &boolval, &intval, &disable);
+ &boolval, &intval, &doubleval, &disable);
if (c == -1)
break;
@@ -346,6 +349,101 @@ Options *parse_commandline(int argc, char *argv[])
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 TV_OVER_SCAN_OPTION:
+
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->tv_over_scan = -2.0;
+ break;
+ }
+
+ if (doubleval >= 0.0 && doubleval <= 1.0) {
+ op->tv_over_scan = doubleval;
+ } else {
+ fprintf(stderr, "Invalid TVOverScan value: %f.\n", doubleval);
+ 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 */
diff --git a/nvidia-xconfig.h b/nvidia-xconfig.h
index b252b6d..c6084ab 100644
--- a/nvidia-xconfig.h
+++ b/nvidia-xconfig.h
@@ -88,8 +88,9 @@ typedef struct {
#define PROBE_ALL_GPUS_BOOL_OPTION 33
#define DYNAMIC_TWINVIEW_BOOL_OPTION 34
#define INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION 35
+#define USE_EVENTS_BOOL_OPTION 36
-#define XCONFIG_BOOL_OPTION_COUNT (INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION + 1)
+#define XCONFIG_BOOL_OPTION_COUNT (USE_EVENTS_BOOL_OPTION + 1)
/* # of 32-bit variables needed to hold all the boolean options (bits) */
#define XCONFIG_BOOL_OPTION_SLOTS \
@@ -140,6 +141,7 @@ typedef struct __options {
int nvagp;
int transparent_index;
int stereo;
+ int cool_bits;
char *xconfig;
char *output_xconfig;
@@ -157,6 +159,10 @@ typedef struct __options {
char *twinview_orientation;
char *use_display_device;
char *custom_edid;
+ char *tv_standard;
+ char *tv_out_format;
+
+ double tv_over_scan;
struct {
int x;
diff --git a/option_table.h b/option_table.h
index 8b59c03..0b19d10 100644
--- a/option_table.h
+++ b/option_table.h
@@ -37,6 +37,10 @@
#define VIRTUAL_OPTION 26
#define USE_DISPLAY_DEVICE_OPTION 27
#define CUSTOM_EDID_OPTION 28
+#define TV_STANDARD_OPTION 29
+#define TV_OUT_FORMAT_OPTION 30
+#define TV_OVER_SCAN_OPTION 31
+#define COOL_BITS_OPTION 32
/*
* To add a boolean option to nvidia-xconfig:
@@ -138,6 +142,13 @@ static const NVGetoptOption __options[] = {
NVGETOPT_IS_BOOLEAN, NULL,
"Disable or enable the \"NoBandWidthTest\" X configuration option." },
+ { "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 settings. Default value is 0.\n"
+ "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." },
@@ -153,8 +164,11 @@ static const NVGetoptOption __options[] = {
{ "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 "
- "in a file rather than the display's EDID." },
+ "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,
@@ -392,7 +406,7 @@ static const NVGetoptOption __options[] = {
"Enable or disable the \"Rotate\" X configuration option. Valid values "
"for [ROTATE] are 'normal', 'left', 'CCW', 'inverted', "
"'right', and 'CW'. Rotation can be disabled " },
-
+
{ "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 "
@@ -425,6 +439,24 @@ static const NVGetoptOption __options[] = {
"clone mode stereo), 5 (SeeReal digital flat panel), 6 (Sharp3D "
"digital flat panel)." },
+ { "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\"." },
+
+ { "tv-over-scan", TV_OVER_SCAN_OPTION,
+ NVGETOPT_DOUBLE_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL,
+ "Enable or disable the \"TVOverScan\" X configuration option. Valid "
+ "values are decimal values in the range 1.0 and 0.0." },
+
{ "twinview", XCONFIG_BOOL_VAL(TWINVIEW_BOOL_OPTION),
NVGETOPT_IS_BOOLEAN, NULL, "Enable or disable TwinView." },
@@ -488,6 +520,14 @@ static const NVGetoptOption __options[] = {
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." },
diff --git a/options.c b/options.c
index 2819f9d..792b8dd 100644
--- a/options.c
+++ b/options.c
@@ -74,6 +74,7 @@ static const NvidiaXConfigOption __options[] = {
{ PROBE_ALL_GPUS_BOOL_OPTION, FALSE, "ProbeAllGpus" },
{ DYNAMIC_TWINVIEW_BOOL_OPTION, FALSE, "DynamicTwinView" },
{ INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION,FALSE, "IncludeImplicitMetaModes" },
+ { USE_EVENTS_BOOL_OPTION, FALSE, "UseEvents" },
{ 0, FALSE, NULL },
};
@@ -513,6 +514,45 @@ void update_options(Options *op, XConfigScreenPtr screen)
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 TVOverScan option */
+
+ if (op->tv_over_scan != -1.0) {
+ remove_option(screen, "TVOverScan");
+ if (op->tv_over_scan != -2.0) {
+ snprintf(scratch, 8, "%f", op->tv_over_scan);
+ set_option_value(screen, "TVOverScan", scratch);
+ }
+ }
+
+ /* 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);
+ }
+ }
+
+
+
} /* update_options() */