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
commit519a7f3cc9b213e2d1e7c94b64bd0d68d16bb872 (patch)
tree46f743cd79dd85d8d16e5ba653f91526fbfd8183
parent80e326c7dff56784314d3ae0087e914b23598a5a (diff)
1.0-96261.0-9626
-rw-r--r--Makefile3
-rw-r--r--XF86Config-parser/DRI.c10
-rw-r--r--XF86Config-parser/Device.c4
-rw-r--r--XF86Config-parser/Files.c6
-rw-r--r--XF86Config-parser/Flags.c14
-rw-r--r--XF86Config-parser/Generate.c108
-rw-r--r--XF86Config-parser/Input.c49
-rw-r--r--XF86Config-parser/Keyboard.c4
-rw-r--r--XF86Config-parser/Layout.c89
-rw-r--r--XF86Config-parser/Makefile58
-rw-r--r--XF86Config-parser/Module.c4
-rw-r--r--XF86Config-parser/Monitor.c12
-rw-r--r--XF86Config-parser/Pointer.c4
-rw-r--r--XF86Config-parser/Read.c33
-rw-r--r--XF86Config-parser/Screen.c78
-rw-r--r--XF86Config-parser/Vendor.c8
-rw-r--r--XF86Config-parser/Video.c8
-rw-r--r--XF86Config-parser/configProcs.h12
-rw-r--r--XF86Config-parser/xf86Parser.h48
-rw-r--r--extract_edids.c725
-rw-r--r--gen-manpage-opts.c61
-rw-r--r--make_usable.c16
-rw-r--r--multiple_screens.c19
-rw-r--r--nvgetopt.c113
-rw-r--r--nvgetopt.h51
-rw-r--r--nvidia-xconfig.c246
-rw-r--r--nvidia-xconfig.h89
-rw-r--r--option_table.h395
-rw-r--r--options.c219
-rw-r--r--tree.c25
30 files changed, 1916 insertions, 595 deletions
diff --git a/Makefile b/Makefile
index d07bec1..84a5608 100644
--- a/Makefile
+++ b/Makefile
@@ -121,7 +121,8 @@ SRC = util.c \
nvgetopt.c \
options.c \
lscf.c \
- query_gpu_info.c
+ query_gpu_info.c \
+ extract_edids.c
ALL_SRC = $(SRC) $(STAMP_C)
diff --git a/XF86Config-parser/DRI.c b/XF86Config-parser/DRI.c
index 03f14d9..9936830 100644
--- a/XF86Config-parser/DRI.c
+++ b/XF86Config-parser/DRI.c
@@ -65,10 +65,6 @@ xconfigParseBuffers (void)
xconfigUnGetToken(token);
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Buffers parsed\n");
-#endif
-
return ptr;
}
@@ -115,11 +111,7 @@ xconfigParseDRISection (void)
break;
}
}
-
-#ifdef DEBUG
- ErrorF("DRI section parsed\n");
-#endif
-
+
return ptr;
}
diff --git a/XF86Config-parser/Device.c b/XF86Config-parser/Device.c
index 29359d8..a4c3f62 100644
--- a/XF86Config-parser/Device.c
+++ b/XF86Config-parser/Device.c
@@ -255,10 +255,6 @@ xconfigParseDeviceSection (void)
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Device section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/Files.c b/XF86Config-parser/Files.c
index 8285c5c..6493cd1 100644
--- a/XF86Config-parser/Files.c
+++ b/XF86Config-parser/Files.c
@@ -55,6 +55,8 @@
/* View/edit this file with tab stops set to 4 */
+#include <strings.h>
+
#include "xf86Parser.h"
#include "xf86tokens.h"
#include "Configint.h"
@@ -196,10 +198,6 @@ xconfigParseFilesSection (void)
}
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "File section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/Flags.c b/XF86Config-parser/Flags.c
index c296b8a..21413c9 100644
--- a/XF86Config-parser/Flags.c
+++ b/XF86Config-parser/Flags.c
@@ -165,10 +165,6 @@ xconfigParseFlagsSection (void)
}
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Flags section parsed\n");
-#endif
-
return ptr;
}
@@ -489,16 +485,6 @@ xconfigULongToString(unsigned long i)
return s;
}
-void
-xconfigDebugListOptions(XConfigOptionPtr Options)
-{
- while (Options) {
- xconfigErrorMsg(DebugMsg, "Option: %s Value: %s\n",
- Options->name, Options->val);
- Options = Options->next;
- }
-}
-
XConfigOptionPtr
xconfigParseOption(XConfigOptionPtr head)
{
diff --git a/XF86Config-parser/Generate.c b/XF86Config-parser/Generate.c
index 1c374cf..d61771a 100644
--- a/XF86Config-parser/Generate.c
+++ b/XF86Config-parser/Generate.c
@@ -52,9 +52,6 @@ static void add_files(GenerateOptions *gop, XConfigPtr config);
static void add_font_path(GenerateOptions *gop, XConfigPtr config);
static void add_modules(GenerateOptions *gop, XConfigPtr config);
-static XConfigMonitorPtr
-add_monitor(XConfigPtr config, int count);
-
static XConfigDevicePtr
add_device(XConfigPtr config, int bus, int slot, char *boardname, int count);
@@ -63,9 +60,6 @@ static void add_layout(GenerateOptions *gop, XConfigPtr config);
static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout,
char *name, char *coreKeyword);
-static int add_keyboard(GenerateOptions *gop, XConfigPtr config);
-static int add_mouse(GenerateOptions *gop, XConfigPtr config);
-
/*
* xconfigGenerate() - generate a new XConfig from scratch
*/
@@ -84,8 +78,8 @@ XConfigPtr xconfigGenerate(GenerateOptions *gop)
/* add the keyboard and mouse */
- add_keyboard(gop, config);
- add_mouse(gop, config);
+ xconfigAddKeyboard(gop, config);
+ xconfigAddMouse(gop, config);
/* add the layout */
@@ -113,7 +107,7 @@ XConfigScreenPtr xconfigGenerateAddScreen(XConfigPtr config,
XConfigDevicePtr device;
XConfigMonitorPtr monitor;
- monitor = add_monitor(config, count);
+ monitor = xconfigAddMonitor(config, count);
device = add_device(config, bus, slot, boardname, count);
screen = xconfigAlloc(sizeof(XConfigScreenRec));
@@ -329,7 +323,7 @@ static void add_font_path(GenerateOptions *gop, XConfigPtr config)
ret = system("ps -C xfs 2>&1 > /dev/null");
#endif
if (WEXITSTATUS(ret) == 0) {
- config->files->fontpath = "unix/:7100";
+ config->files->fontpath = xconfigStrdup("unix/:7100");
} else {
/* get the X server libdir */
@@ -400,25 +394,23 @@ static void add_modules(GenerateOptions *gop, XConfigPtr config)
config->modules = xconfigAlloc(sizeof(XConfigModuleRec));
- l = xconfigAddNewLoadDirective(l, "dbe", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
- l = xconfigAddNewLoadDirective(l, "extmod", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
- l = xconfigAddNewLoadDirective(l, "type1", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("dbe"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("extmod"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("type1"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
#if defined(NV_SUNOS)
- l = xconfigAddNewLoadDirective(l, "IA", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
- l = xconfigAddNewLoadDirective(l, "Xst", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
- l = xconfigAddNewLoadDirective(l, "bitstream", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("IA"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("bitstream"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
#else
- l = xconfigAddNewLoadDirective(l, "freetype", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("freetype"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
#endif
- l = xconfigAddNewLoadDirective(l, "glx", XCONFIG_LOAD_MODULE,
- NULL, FALSE);
+ l = xconfigAddNewLoadDirective(l, xconfigStrdup("glx"),
+ XCONFIG_LOAD_MODULE, NULL, FALSE);
config->modules->loads = l;
@@ -427,13 +419,12 @@ static void add_modules(GenerateOptions *gop, XConfigPtr config)
/*
- * add_monitor() -
+ * xconfigAddMonitor() -
*
* XXX pass EDID values into this...
*/
-static XConfigMonitorPtr
-add_monitor(XConfigPtr config, int count)
+XConfigMonitorPtr xconfigAddMonitor(XConfigPtr config, int count)
{
XConfigMonitorPtr monitor, m;
XConfigOptionPtr opt = NULL;
@@ -444,8 +435,8 @@ add_monitor(XConfigPtr config, int count)
monitor->identifier = xconfigAlloc(32);
snprintf(monitor->identifier, 32, MONITOR_IDENTIFIER, count);
- monitor->vendor = "Unknown"; /* XXX */
- monitor->modelname = "Unknown"; /* XXX */
+ monitor->vendor = xconfigStrdup("Unknown"); /* XXX */
+ monitor->modelname = xconfigStrdup("Unknown"); /* XXX */
/* XXX check EDID for freq ranges */
@@ -472,7 +463,7 @@ add_monitor(XConfigPtr config, int count)
return monitor;
-} /* add_monitor() */
+} /* xconfigAddMonitor() */
@@ -563,7 +554,7 @@ static void add_layout(GenerateOptions *gop, XConfigPtr config)
layout = xconfigAlloc(sizeof(XConfigLayoutRec));
- layout->identifier = "Layout0";
+ layout->identifier = xconfigStrdup("Layout0");
adj = xconfigAlloc(sizeof(XConfigAdjacencyRec));
@@ -595,7 +586,7 @@ static void add_inputref(XConfigPtr config, XConfigLayoutPtr layout,
XConfigInputrefPtr inputRef;
inputRef = xconfigAlloc(sizeof(XConfigInputrefRec));
- inputRef->input_name = name;
+ inputRef->input_name = xconfigStrdup(name);
inputRef->input = xconfigFindInput(inputRef->input_name, config->inputs);
inputRef->options =
xconfigAddNewOption(NULL, xconfigStrdup(coreKeyword), NULL);
@@ -930,7 +921,7 @@ void xconfigGeneratePrintPossibleMice(void)
/*
- * add_mouse() - determine the mouse type, and then add an
+ * xconfigAddMouse() - determine the mouse type, and then add an
* XConfigInputRec with the appropriate options.
*
* - if the user specified on the commandline, use that
@@ -945,7 +936,7 @@ void xconfigGeneratePrintPossibleMice(void)
* - default to "auto" on /dev/mouse
*/
-static int add_mouse(GenerateOptions *gop, XConfigPtr config)
+int xconfigAddMouse(GenerateOptions *gop, XConfigPtr config)
{
const MouseEntry *entry = NULL;
XConfigInputPtr input;
@@ -1020,6 +1011,9 @@ static int add_mouse(GenerateOptions *gop, XConfigPtr config)
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) {
@@ -1027,7 +1021,7 @@ static int add_mouse(GenerateOptions *gop, XConfigPtr config)
} else {
e->device = "mouse";
}
-
+#endif
e->emulate3 = FALSE;
entry = e;
}
@@ -1038,12 +1032,13 @@ static int add_mouse(GenerateOptions *gop, XConfigPtr config)
input->comment = xconfigStrcat(" # generated from ",
comment, "\n", NULL);
- input->identifier = "Mouse0";
- input->driver = "mouse";
+ input->identifier = xconfigStrdup("Mouse0");
+ input->driver = xconfigStrdup("mouse");
device_path = xconfigStrcat("/dev/", entry->device, NULL);
- opt = xconfigAddNewOption(opt, xconfigStrdup("Protocol"), entry->Xproto);
+ opt = xconfigAddNewOption(opt, xconfigStrdup("Protocol"),
+ xconfigStrdup(entry->Xproto));
opt = xconfigAddNewOption(opt, xconfigStrdup("Device"), device_path);
opt = xconfigAddNewOption(opt, xconfigStrdup("Emulate3Buttons"),
entry->emulate3 ?
@@ -1054,7 +1049,8 @@ static int add_mouse(GenerateOptions *gop, XConfigPtr config)
* ignore ZAxisMapping
*/
- opt = xconfigAddNewOption(opt, "ZAxisMapping", "4 5");
+ opt = xconfigAddNewOption(opt, xconfigStrdup("ZAxisMapping"),
+ xconfigStrdup("4 5"));
input->options = opt;
@@ -1063,7 +1059,7 @@ static int add_mouse(GenerateOptions *gop, XConfigPtr config)
return TRUE;
-} /* add_mouse() */
+} /* xconfigAddMouse() */
@@ -1223,7 +1219,7 @@ void xconfigGeneratePrintPossibleKeyboards(void)
/*
- * add_keyboard() - determine the keyboard type, and then add an
+ * xconfigAddKeyboard() - determine the keyboard type, and then add an
* XConfigInputRec with the appropriate options.
*
* How to detect the keyboard:
@@ -1234,7 +1230,7 @@ void xconfigGeneratePrintPossibleKeyboards(void)
* KEYTABLE entry, use that
*/
-static int add_keyboard(GenerateOptions *gop, XConfigPtr config)
+int xconfigAddKeyboard(GenerateOptions *gop, XConfigPtr config)
{
char *value, *comment = "default";
const KeyboardEntry *entry = NULL;
@@ -1245,7 +1241,7 @@ static int add_keyboard(GenerateOptions *gop, XConfigPtr config)
/*
* if the user specified on the command line, use that
*/
-
+
if (gop->keyboard) {
entry = find_keyboard_entry(gop->keyboard);
if (entry) {
@@ -1278,7 +1274,7 @@ static int add_keyboard(GenerateOptions *gop, XConfigPtr config)
input->comment = xconfigStrcat(" # generated from ",
comment, "\n", NULL);
- input->identifier = "Keyboard0";
+ input->identifier = xconfigStrdup("Keyboard0");
/*
* determine which keyboard driver should be used (either "kbd" or
@@ -1292,12 +1288,12 @@ static int add_keyboard(GenerateOptions *gop, XConfigPtr config)
input->driver = gop->keyboard_driver;
} else {
#if defined(NV_SUNOS) || defined(NV_BSD)
- input->driver = "keyboard";
+ input->driver = xconfigStrdup("keyboard");
#else
if (gop->xserver == X_IS_XORG) {
- input->driver = "kbd";
+ input->driver = xconfigStrdup("kbd");
} else {
- input->driver = "keyboard";
+ input->driver = xconfigStrdup("keyboard");
}
#endif
}
@@ -1309,16 +1305,20 @@ static int add_keyboard(GenerateOptions *gop, XConfigPtr config)
if (entry && entry->layout)
opt = xconfigAddNewOption(opt,
- xconfigStrdup("XkbLayout"), entry->layout);
+ xconfigStrdup("XkbLayout"),
+ xconfigStrdup(entry->layout));
if (entry && entry->model)
opt = xconfigAddNewOption(opt,
- xconfigStrdup("XkbModel"), entry->model);
+ xconfigStrdup("XkbModel"),
+ xconfigStrdup(entry->model));
if (entry && entry->variant)
opt = xconfigAddNewOption(opt,
- xconfigStrdup("XkbVariant"), entry->variant);
+ xconfigStrdup("XkbVariant"),
+ xconfigStrdup(entry->variant));
if (entry && entry->options)
opt = xconfigAddNewOption(opt,
- xconfigStrdup("XkbOptions"), entry->options);
+ xconfigStrdup("XkbOptions"),
+ xconfigStrdup(entry->options));
input->options = opt;
@@ -1327,4 +1327,4 @@ static int add_keyboard(GenerateOptions *gop, XConfigPtr config)
return TRUE;
-} /* add_keyboard() */
+} /* xconfigAddKeyboard() */
diff --git a/XF86Config-parser/Input.c b/XF86Config-parser/Input.c
index b368ba7..1665600 100644
--- a/XF86Config-parser/Input.c
+++ b/XF86Config-parser/Input.c
@@ -115,10 +115,6 @@ xconfigParseInputSection (void)
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "InputDevice section parsed\n");
-#endif
-
return ptr;
}
@@ -212,8 +208,10 @@ xconfigFindInputByDriver (const char *driver, XConfigInputPtr p)
-static int getCoreInputDevice(XConfigPtr config,
+static int getCoreInputDevice(GenerateOptions *gop,
+ XConfigPtr config,
XConfigLayoutPtr layout,
+ const int mouse,
const char *coreKeyword,
const char *implicitDriverName,
const char *defaultDriver0,
@@ -223,7 +221,7 @@ static int getCoreInputDevice(XConfigPtr config,
{
XConfigInputPtr input, core = NULL;
XConfigInputrefPtr inputRef;
- int found;
+ int found, firstTry;
const char *found_msg = NULL;
/*
@@ -281,19 +279,45 @@ static int getCoreInputDevice(XConfigPtr config,
* 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(defaultDriver0, config->inputs);
+ 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
@@ -367,13 +391,16 @@ static int getCoreInputDevice(XConfigPtr config,
* be added from the current list of input devices.
*/
-int xconfigCheckCoreInputDevices(XConfigPtr config,
+int xconfigCheckCoreInputDevices(GenerateOptions *gop,
+ XConfigPtr config,
XConfigLayoutPtr layout)
{
int ret;
- ret = getCoreInputDevice(config,
+ ret = getCoreInputDevice(gop,
+ config,
layout,
+ TRUE,
"CorePointer",
CONF_IMPLICIT_POINTER,
"mouse", NULL,
@@ -382,8 +409,10 @@ int xconfigCheckCoreInputDevices(XConfigPtr config,
if (!ret) return FALSE;
- ret = getCoreInputDevice(config,
+ ret = getCoreInputDevice(gop,
+ config,
layout,
+ FALSE,
"CoreKeyboard",
CONF_IMPLICIT_KEYBOARD,
"keyboard", "kbd",
diff --git a/XF86Config-parser/Keyboard.c b/XF86Config-parser/Keyboard.c
index 753fbf1..26bbb73 100644
--- a/XF86Config-parser/Keyboard.c
+++ b/XF86Config-parser/Keyboard.c
@@ -299,10 +299,6 @@ xconfigParseKeyboardSection (void)
ptr->options = xconfigAddNewOption(ptr->options,
xconfigStrdup("CoreKeyboard"), NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Keyboard section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/Layout.c b/XF86Config-parser/Layout.c
index 46cea64..1e62d26 100644
--- a/XF86Config-parser/Layout.c
+++ b/XF86Config-parser/Layout.c
@@ -281,10 +281,6 @@ xconfigParseLayoutSection (void)
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Layout section parsed\n");
-#endif
-
return ptr;
}
@@ -431,19 +427,22 @@ else \
}
int
-xconfigValidateLayout (XConfigPtr p, const char *screenName)
+xconfigValidateLayout (XConfigPtr p)
{
XConfigLayoutPtr layout = p->layouts;
XConfigAdjacencyPtr adj;
XConfigInactivePtr iptr;
- XConfigInputrefPtr inptr;
+ XConfigInputrefPtr inputRef;
XConfigScreenPtr screen;
XConfigDevicePtr device;
XConfigInputPtr input;
- if (!layout) {
- if (!addImpliedLayout(p, screenName)) return FALSE;
- }
+ /*
+ * 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)
{
@@ -470,6 +469,9 @@ xconfigValidateLayout (XConfigPtr p, const char *screenName)
adj = adj->next;
}
+
+ /* I not believe the "inactives" list is used for anything */
+
iptr = layout->inactives;
while (iptr)
{
@@ -485,27 +487,60 @@ xconfigValidateLayout (XConfigPtr p, const char *screenName)
iptr->device = device;
iptr = iptr->next;
}
- inptr = layout->inputs;
- while (inptr)
+
+ /*
+ * 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 (inptr->input_name,
+ input = xconfigFindInput (inputRef->input_name,
p->inputs);
if (!input)
{
xconfigErrorMsg(ValidationErrorMsg, UNDEFINED_INPUT_MSG,
- inptr->input_name, layout->identifier);
+ inputRef->input_name, layout->identifier);
return (FALSE);
}
else {
- inptr->input = input;
+ inputRef->input = input;
}
- inptr = inptr->next;
+ 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)
{
@@ -535,12 +570,12 @@ static int addImpliedLayout(XConfigPtr config, const char *screenName)
*/
if (screenName) {
- screen = xconfigFindScreen(screenName, config->screens);
+ screen = xconfigFindScreen(screenName, config->screens);
if (!screen) {
xconfigErrorMsg(ErrorMsg, "No Screen section called \"%s\"\n",
screenName);
- return FALSE;
- }
+ return FALSE;
+ }
} else {
screen = config->screens;
}
@@ -553,28 +588,20 @@ static int addImpliedLayout(XConfigPtr config, const char *screenName)
layout = calloc(1, sizeof(XConfigLayoutRec));
- layout->identifier = "Default Layout";
+ layout->identifier = xconfigStrdup("Default Layout");
adj = calloc(1, sizeof(XConfigAdjacencyRec));
adj->scrnum = -1;
adj->screen = screen;
- adj->screen_name = strdup(screen->identifier);
+ adj->screen_name = xconfigStrdup(screen->identifier);
layout->adjacencies = adj;
config->layouts = layout;
+
+ /* validate the Layout here to setup all the pointers */
- /*
- * xconfigCheckCoreInputDevices() will add a keyboard and mouse to
- * the layout.
- */
+ if (!xconfigValidateLayout(config)) return FALSE;
- if (!xconfigCheckCoreInputDevices(config, layout)) {
- free(adj);
- free(layout);
- config->layouts = NULL;
- return FALSE;
- }
-
return TRUE;
}
diff --git a/XF86Config-parser/Makefile b/XF86Config-parser/Makefile
index 34a206a..ef973a6 100644
--- a/XF86Config-parser/Makefile
+++ b/XF86Config-parser/Makefile
@@ -1,24 +1,30 @@
-SRC = DRI.c \
- Device.c \
- Files.c \
- Flags.c \
- Input.c \
- Keyboard.c \
- Layout.c \
- Module.c \
- Monitor.c \
- Pointer.c \
- Screen.c \
- Vendor.c \
- Video.c \
- Read.c \
- Scan.c \
- Write.c \
- Util.c \
- Extensions.c \
+SRC = \
+ DRI.c \
+ Device.c \
+ Files.c \
+ Flags.c \
+ Input.c \
+ Keyboard.c \
+ Layout.c \
+ Module.c \
+ Monitor.c \
+ Pointer.c \
+ Screen.c \
+ Vendor.c \
+ Video.c \
+ Read.c \
+ Scan.c \
+ Write.c \
+ Util.c \
+ Extensions.c \
Generate.c
-OBJS = $(SRC:.c=.o)
+OBJS = $(SRC:%.c=%.o)
+DEPS = $(SRC:%.c=%.d)
+
+ifndef CC
+ CC = gcc
+endif
CFLAGS = -Wall -g
@@ -26,13 +32,21 @@ ifdef NV_CFLAGS
CFLAGS += $(NV_CFLAGS)
endif
+ifndef RANLIB
+ RANLIB = ranlib
+endif
+
LIB = libXF86Config-parser.a
-LIB_O = $(LIB:.a=.o)
+LIB_O = $(LIB:%.a=%.o)
+
+default all: $(LIB)
+
+.PHONY: clean clobber
$(LIB): $(OBJS)
$(LD) -r -o $(LIB_O) $(OBJS)
$(AR) ruv $(LIB) $(LIB_O)
- ranlib $(LIB)
+ $(RANLIB) $(LIB)
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
@@ -45,4 +59,4 @@ $(LIB): $(OBJS)
clean clobber:
rm -rf *.o *~ *.d $(LIB) $(LIB_O)
--include $(SRC:.c=.d)
+-include $(DEPS)
diff --git a/XF86Config-parser/Module.c b/XF86Config-parser/Module.c
index e7e7a42..0605367 100644
--- a/XF86Config-parser/Module.c
+++ b/XF86Config-parser/Module.c
@@ -160,10 +160,6 @@ xconfigParseModuleSection (void)
}
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Module section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/Monitor.c b/XF86Config-parser/Monitor.c
index c657fd4..8c273c4 100644
--- a/XF86Config-parser/Monitor.c
+++ b/XF86Config-parser/Monitor.c
@@ -243,9 +243,6 @@ xconfigParseModeLine (void)
}
xconfigUnGetToken (token);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "ModeLine parsed\n");
-#endif
return (ptr);
}
@@ -392,9 +389,6 @@ xconfigParseVerboseMode (void)
if (!had_vtimings)
Error ("the vertical timings are missing", NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Verbose Mode parsed\n");
-#endif
return (ptr);
}
@@ -586,9 +580,6 @@ VertDone:
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Monitor section parsed\n");
-#endif
return ptr;
}
@@ -637,9 +628,6 @@ xconfigParseModesSection (void)
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Modes section parsed\n");
-#endif
return ptr;
}
diff --git a/XF86Config-parser/Pointer.c b/XF86Config-parser/Pointer.c
index bc2ceb3..d1e282a 100644
--- a/XF86Config-parser/Pointer.c
+++ b/XF86Config-parser/Pointer.c
@@ -229,10 +229,6 @@ xconfigParsePointerSection (void)
ptr->options = xconfigAddNewOption(ptr->options,
xconfigStrdup("CorePointer"), NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Pointer section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/Read.c b/XF86Config-parser/Read.c
index 4e76d2e..7d21e44 100644
--- a/XF86Config-parser/Read.c
+++ b/XF86Config-parser/Read.c
@@ -98,12 +98,10 @@ static XConfigSymTabRec TopLevelTab[] =
/*
* xconfigReadConfigFile() - read the open XConfig file, returning the
- * parsed data as XConfigPtr. The screenName argument is used
- * during validation in the case that no layout was specified and we
- * have to build an implicit layout and need to choose a screen.
+ * parsed data as XConfigPtr.
*/
-XConfigError xconfigReadConfigFile(const char *screenName, XConfigPtr *configPtr)
+XConfigError xconfigReadConfigFile(XConfigPtr *configPtr)
{
int token;
XConfigPtr ptr = NULL;
@@ -245,7 +243,7 @@ XConfigError xconfigReadConfigFile(const char *screenName, XConfigPtr *configPtr
}
}
- if (xconfigValidateConfig(ptr, screenName)) {
+ if (xconfigValidateConfig(ptr)) {
ptr->filename = strdup(xconfigGetConfigFileName());
*configPtr = ptr;
return XCONFIG_RETURN_SUCCESS;
@@ -263,7 +261,7 @@ XConfigError xconfigReadConfigFile(const char *screenName, XConfigPtr *configPtr
* objects cannot be found.
*/
-int xconfigValidateConfig(XConfigPtr p, const char *screenName)
+int xconfigValidateConfig(XConfigPtr p)
{
if (!xconfigValidateDevice(p))
return FALSE;
@@ -271,13 +269,34 @@ int xconfigValidateConfig(XConfigPtr p, const char *screenName)
return FALSE;
if (!xconfigValidateInput(p))
return FALSE;
- if (!xconfigValidateLayout(p, screenName))
+ 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.
diff --git a/XF86Config-parser/Screen.c b/XF86Config-parser/Screen.c
index 62e4730..f58d76b 100644
--- a/XF86Config-parser/Screen.c
+++ b/XF86Config-parser/Screen.c
@@ -190,10 +190,6 @@ xconfigParseDisplaySubSection (void)
}
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Display subsection parsed\n");
-#endif
-
return ptr;
}
@@ -323,10 +319,6 @@ xconfigParseScreenSection (void)
if (!has_ident && !has_driver)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Screen section parsed\n");
-#endif
-
return ptr;
}
@@ -563,6 +555,64 @@ xconfigValidateScreen (XConfigPtr p)
return (TRUE);
}
+int xconfigSanitizeScreen(XConfigPtr p)
+{
+ XConfigScreenPtr screen = p->screens;
+ XConfigMonitorPtr monitor;
+
+ 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)
{
@@ -576,6 +626,18 @@ xconfigFindScreen (const char *ident, XConfigScreenPtr p)
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);
+}
XConfigModePtr
xconfigAddMode(XConfigModePtr head, const char *name)
diff --git a/XF86Config-parser/Vendor.c b/XF86Config-parser/Vendor.c
index aa57005..7f6beba 100644
--- a/XF86Config-parser/Vendor.c
+++ b/XF86Config-parser/Vendor.c
@@ -106,10 +106,6 @@ xconfigParseVendorSubSection (void)
}
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Vendor subsection parsed\n");
-#endif
-
return ptr;
}
@@ -172,10 +168,6 @@ xconfigParseVendorSection (void)
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "Vendor section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/Video.c b/XF86Config-parser/Video.c
index 12846b2..a09d7f7 100644
--- a/XF86Config-parser/Video.c
+++ b/XF86Config-parser/Video.c
@@ -105,10 +105,6 @@ xconfigParseVideoPortSubSection (void)
}
}
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "VideoPort subsection parsed\n");
-#endif
-
return ptr;
}
@@ -196,10 +192,6 @@ xconfigParseVideoAdaptorSection (void)
if (!has_ident)
Error (NO_IDENT_MSG, NULL);
-#ifdef DEBUG
- xconfigErrorMsg(DebugMsg, "VideoAdaptor section parsed\n");
-#endif
-
return ptr;
}
diff --git a/XF86Config-parser/configProcs.h b/XF86Config-parser/configProcs.h
index f8b0c24..59bac71 100644
--- a/XF86Config-parser/configProcs.h
+++ b/XF86Config-parser/configProcs.h
@@ -54,7 +54,9 @@ XConfigInputPtr xconfigParseKeyboardSection(void);
/* Layout.c */
XConfigLayoutPtr xconfigParseLayoutSection(void);
void xconfigPrintLayoutSection(FILE *cf, XConfigLayoutPtr ptr);
-int xconfigValidateLayout(XConfigPtr p, const char *screenName);
+int xconfigValidateLayout(XConfigPtr p);
+int xconfigSanitizeLayout(XConfigPtr p, const char *screenName,
+ GenerateOptions *gop);
/* Module.c */
XConfigLoadPtr xconfigParseModuleSubSection(XConfigLoadPtr head, char *name);
@@ -78,6 +80,7 @@ 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);
@@ -90,7 +93,7 @@ XConfigVideoAdaptorPtr xconfigParseVideoAdaptorSection(void);
void xconfigPrintVideoAdaptorSection(FILE *cf, XConfigVideoAdaptorPtr ptr);
/* Read.c */
-int xconfigValidateConfig(XConfigPtr p, const char *);
+int xconfigValidateConfig(XConfigPtr p);
/* Scan.c */
int xconfigGetToken(XConfigSymTabRec *tab);
@@ -116,3 +119,8 @@ 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/XF86Config-parser/xf86Parser.h b/XF86Config-parser/xf86Parser.h
index e47e108..40b8162 100644
--- a/XF86Config-parser/xf86Parser.h
+++ b/XF86Config-parser/xf86Parser.h
@@ -578,12 +578,30 @@ typedef struct {
} XConfigSymTabRec, *XConfigSymTabPtr;
+/*
+ * data structure containing options; used during generation of X
+ * config, and when sanitizing an existing config
+ */
+
+#define X_IS_XF86 0
+#define X_IS_XORG 1
+
+typedef struct {
+ int xserver;
+ char *x_project_root;
+ char *keyboard;
+ char *mouse;
+ char *keyboard_driver;
+} GenerateOptions;
+
/*
* Functions for open, reading, and writing XConfig files.
*/
const char *xconfigOpenConfigFile(const char *, const char *);
-XConfigError xconfigReadConfigFile(const char *, XConfigPtr *);
+XConfigError xconfigReadConfigFile(XConfigPtr *);
+int xconfigSanitizeConfig(XConfigPtr p, const char *screenName,
+ GenerateOptions *gop);
void xconfigCloseConfigFile(void);
int xconfigWriteConfigFile(const char *, XConfigPtr);
@@ -600,6 +618,7 @@ 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);
@@ -636,13 +655,6 @@ void xconfigFreeExtensions(XConfigExtensionsPtr ptr);
/*
- * check (and update, if necessary) the inputs in the specified layout
- * section
- */
-
-int xconfigCheckCoreInputDevices(XConfigPtr config, XConfigLayoutPtr layout);
-
-/*
* item/list manipulation
*/
@@ -689,7 +701,6 @@ char *xconfigStrcat(const char *str, ...);
int xconfigNameCompare(const char *s1, const char *s2);
int xconfigModelineCompare(XConfigModeLinePtr m1, XConfigModeLinePtr m2);
char *xconfigULongToString(unsigned long i);
-void xconfigDebugListOptions(XConfigOptionPtr);
XConfigOptionPtr xconfigParseOption(XConfigOptionPtr head);
void xconfigPrintOptionList(FILE *fp, XConfigOptionPtr list, int tabs);
int xconfigParsePciBusString(const char *busID,
@@ -705,17 +716,6 @@ XConfigModePtr
xconfigRemoveMode(XConfigModePtr head, const char *name);
-#define X_IS_XF86 0
-#define X_IS_XORG 1
-
-typedef struct {
- int xserver;
- char *x_project_root;
- char *keyboard;
- char *mouse;
- char *keyboard_driver;
-} GenerateOptions;
-
XConfigPtr xconfigGenerate(GenerateOptions *gop);
XConfigScreenPtr xconfigGenerateAddScreen(XConfigPtr config, int bus, int slot,
@@ -726,4 +726,12 @@ void xconfigGenerateAssignScreenAdjacencies(XConfigLayoutPtr layout);
void xconfigGeneratePrintPossibleMice(void);
void xconfigGeneratePrintPossibleKeyboards(void);
+/*
+ * check (and update, if necessary) the inputs in the specified layout
+ * section
+ */
+
+int xconfigCheckCoreInputDevices(GenerateOptions *gop,
+ XConfigPtr config, XConfigLayoutPtr layout);
+
#endif /* _xf86Parser_h_ */
diff --git a/extract_edids.c b/extract_edids.c
new file mode 100644
index 0000000..9fc1603
--- /dev/null
+++ b/extract_edids.c
@@ -0,0 +1,725 @@
+/*
+ * 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 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.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ *
+ * extract-edids.c
+ *
+ * This source file gives us the means to extract EDIDs from verbose X
+ * log 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):
+ * (--) NVIDIA(0): --- End of EDID for ViewSonic VPD150 (DFP-1) ---
+ *
+ * We read a log file, identify and read any EDID(s) contained in the
+ * log 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.
+ * This utility is included in nvidia-xconfig, since maybe users will
+ * find use for this, too.
+ */
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <stdarg.h>
+
+#include "nvidia-xconfig.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"
+
+
+typedef struct {
+ int size;
+ unsigned char *bytes;
+ char *name;
+} EdidRec, *EdidPtr;
+
+typedef struct {
+ char *start;
+ size_t length;
+ char *current;
+} FileRec, *FilePtr;
+
+
+
+static EdidPtr findEdid(FilePtr pFile);
+
+static int findEdidHeader(FilePtr pFile);
+static int readEdidData(FilePtr pFile, EdidPtr pEdid);
+static int readEdidFooter(FilePtr pFile, EdidPtr pEdid);
+
+static char *findFileName(char *option);
+static int writeEdidFile(EdidPtr pEdid, char *filename);
+
+static void freeEdid(EdidPtr pEdid);
+
+
+
+/*
+ * extract_edids() - see description at the top of this file
+ */
+
+int extract_edids(Options *op)
+{
+ int fd = -1, ret, funcRet = FALSE;
+ char *filename;
+
+ struct stat stat_buf;
+
+ FileRec file;
+ EdidPtr pEdid, *pEdids;
+ int nEdids, i;
+
+ nEdids = 0;
+ pEdids = NULL;
+
+ memset(&file, 0, sizeof(FileRec));
+ file.start = (void *) -1;
+
+ /* open the file and get its length */
+
+ fd = open(op->extract_edids_from_log, O_RDONLY);
+
+ if (fd == -1) {
+ fmterr("Unable to open file \"%s\".", op->extract_edids_from_log);
+ goto done;
+ }
+
+ ret = fstat(fd, &stat_buf);
+
+ if (ret == -1) {
+ fmterr("Unable to get length of file \"%s\".",
+ op->extract_edids_from_log);
+ goto done;
+ }
+
+ file.length = stat_buf.st_size;
+
+ if (file.length == 0) {
+ fmterr("File \"%s\" is empty.", op->extract_edids_from_log);
+ goto done;
+ }
+
+ /* mmap the file */
+
+ file.start = mmap(0, file.length, PROT_READ,
+ MAP_SHARED, fd, 0);
+
+ if (file.start == (void *) -1) {
+ fmterr("Unable to map file \"%s\".", op->extract_edids_from_log);
+ goto done;
+ }
+
+ /* start parsing at the start of file */
+
+ file.current = file.start;
+
+ /* scan through the whole file, and build a list of pEdids */
+
+ while(1) {
+
+ pEdid = findEdid(&file);
+
+ if (!pEdid) break;
+
+ pEdids = nvrealloc(pEdids, sizeof(pEdids) * (nEdids + 1));
+
+ pEdids[nEdids] = pEdid;
+ nEdids++;
+ }
+
+ /* 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
+ */
+
+ fmtout("");
+ fmtout("Found %d EDID%s in \"%s\".",
+ nEdids, (nEdids == 1) ? "": "s", op->extract_edids_from_log);
+
+ 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);
+
+ fmtout("");
+
+ return funcRet;
+
+} // extract_edids()
+
+
+
+/*
+ * 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 findEdid(FilePtr pFile)
+{
+ EdidPtr pEdid = nvalloc(sizeof(EdidRec));
+
+ if (!findEdidHeader(pFile)) goto fail;
+
+ if (!readEdidData(pFile, pEdid)) goto fail;
+
+ if (!readEdidFooter(pFile, pEdid)) goto fail;
+
+ return pEdid;
+
+ fail:
+
+ freeEdid(pEdid);
+
+ return NULL;
+
+} // findEdid()
+
+
+
+
+
+/*
+ * 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 findEdidHeader(FilePtr pFile)
+{
+ while (((pFile->current - pFile->start) + 15) <= pFile->length) {
+
+ if ((pFile->current[0] == 'R') &&
+ (pFile->current[1] == 'a') &&
+ (pFile->current[2] == 'w') &&
+ (pFile->current[3] == ' ') &&
+ (pFile->current[4] == 'E') &&
+ (pFile->current[5] == 'D') &&
+ (pFile->current[6] == 'I') &&
+ (pFile->current[7] == 'D') &&
+ (pFile->current[8] == ' ') &&
+ (pFile->current[9] == 'b') &&
+ (pFile->current[10] == 'y') &&
+ (pFile->current[11] == 't') &&
+ (pFile->current[12] == 'e') &&
+ (pFile->current[13] == 's') &&
+ (pFile->current[14] == ':')) {
+
+ pFile->current += 15;
+ return TRUE;
+ }
+ pFile->current++;
+ }
+
+ return FALSE;
+
+} // findEdidHeader()
+
+
+
+/*
+ * 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_END_OF_LABEL 2
+
+#define MAX_EDID_SIZE 4096
+
+static int readEdidData(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_END_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 find the text "--- End of EDID for ... ---", then
+ * we want to parse that to find out the name of the
+ * display device whose EDID we are reading; this is also
+ * our exit condition for the state machine
+ */
+
+ if (c == '-') {
+ goto done;
+ }
+
+ 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 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;
+ }
+
+ /*
+ * anything else is assumed to be text within the label,
+ * so just ignore it
+ */
+
+ 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;
+
+} // readEdidData()
+
+
+
+/*
+ * readEdidFooter() - the EDID footer is in the form:
+ *
+ * --- End of EDID for [dpy name] ---
+ *
+ * Parse the footer to get the dpy name. pFile->current is expected
+ * to point at the start of the footer. On success, pEdid->name is
+ * assigned and TRUE is returned. On failure, FALSE is returned.
+ */
+
+static int readEdidFooter(FilePtr pFile, EdidPtr pEdid)
+{
+ char *begin;
+ int len;
+
+ /* check that the mapping is large enough */
+
+ if (((pFile->current - pFile->start) + 20) > pFile->length) {
+ return FALSE;
+ }
+
+ /* make sure that the expected text is there */
+
+ if ((pFile->current[0] != '-') ||
+ (pFile->current[1] != '-') ||
+ (pFile->current[2] != '-') ||
+ (pFile->current[3] != ' ') ||
+ (pFile->current[4] != 'E') ||
+ (pFile->current[5] != 'n') ||
+ (pFile->current[6] != 'd') ||
+ (pFile->current[7] != ' ') ||
+ (pFile->current[8] != 'o') ||
+ (pFile->current[9] != 'f') ||
+ (pFile->current[10] != ' ') ||
+ (pFile->current[11] != 'E') ||
+ (pFile->current[12] != 'D') ||
+ (pFile->current[13] != 'I') ||
+ (pFile->current[14] != 'D') ||
+ (pFile->current[15] != ' ') ||
+ (pFile->current[16] != 'f') ||
+ (pFile->current[17] != 'o') ||
+ (pFile->current[18] != 'r') ||
+ (pFile->current[19] != ' ')) {
+
+ return FALSE;
+ }
+
+ /* skip past the start */
+
+ pFile->current += 20;
+
+ begin = pFile->current;
+
+ /* search for the end of the expected text */
+
+ while (((pFile->current - pFile->start) + 5) <= pFile->length) {
+
+ if ((pFile->current[0] == ' ') &&
+ (pFile->current[1] == '-') &&
+ (pFile->current[2] == '-') &&
+ (pFile->current[3] == '-')) {
+
+ len = pFile->current - begin;
+
+ /* 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;
+ }
+
+ pFile->current++;
+ }
+
+ return FALSE;
+
+} // readEdidFooter()
+
+
+
+/*
+ * 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 nvstrdup(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 = nvstrdup(filename);
+
+ 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) {
+ fmtout(" Wrote EDID for \"%s\" to \"%s\" (%d bytes).",
+ pEdid->name, working_filename, pEdid->size);
+ } else {
+ fmterr("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/gen-manpage-opts.c b/gen-manpage-opts.c
index 03bde3e..402e559 100644
--- a/gen-manpage-opts.c
+++ b/gen-manpage-opts.c
@@ -16,30 +16,57 @@ static void print_option(const NVGetoptOption *o)
int j, len;
int omitWhiteSpace;
-
- printf(".TP\n.BI ");
+
+ /* 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 (o->flags & NVGETOPT_IS_BOOLEAN) {
- /* "\-\-name, \-\-no\-name */
- printf("\"\\-\\-%s, \\-\\-no\\-%s", o->name, o->name);
- } else if (isalpha(o->val)) {
- /* "\-c, \-\-name */
- printf("\"\\-%c, \\-\\-%s", o->val, o->name);
- } else {
- /* "\-\-name */
- printf("\"\\-\\-%s", 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) {
- len = strlen(o->name);
- for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]);
- scratch[len] = '\0';
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! */
diff --git a/make_usable.c b/make_usable.c
index c372186..920a7dc 100644
--- a/make_usable.c
+++ b/make_usable.c
@@ -32,6 +32,7 @@
#include "nvidia-xconfig.h"
#include "xf86Parser.h"
+#include "configProcs.h"
static int update_device(XConfigPtr config, XConfigDevicePtr device);
@@ -49,6 +50,10 @@ int update_modules(XConfigPtr config)
XConfigLoadPtr load, next;
int found;
+ if (config->modules == NULL) {
+ config->modules = xconfigAlloc(sizeof(XConfigModuleRec));
+ }
+
/* make sure glx is loaded */
found = FALSE;
@@ -153,7 +158,7 @@ int update_extensions(Options *op, XConfigPtr config)
{
char *value;
- if (GET_BOOL_OPTION(op->boolean_options, COMPOSITE_OPTION)) {
+ if (GET_BOOL_OPTION(op->boolean_options, COMPOSITE_BOOL_OPTION)) {
/* if we don't already have the Extensions section, create it now */
@@ -167,7 +172,8 @@ int update_extensions(Options *op, XConfigPtr config)
/* determine the value to set for the Composite option */
- value = GET_BOOL_OPTION(op->boolean_option_values, COMPOSITE_OPTION) ?
+ value = GET_BOOL_OPTION(op->boolean_option_values,
+ COMPOSITE_BOOL_OPTION) ?
"Enable" : "Disable";
/* add the option */
@@ -300,11 +306,7 @@ static void update_display(Options *op, XConfigScreenPtr screen)
XConfigDisplayPtr display;
XConfigModePtr mode = NULL;
- mode = xconfigAddMode(mode, "640x480");
- mode = xconfigAddMode(mode, "800x600");
- mode = xconfigAddMode(mode, "1024x768");
- mode = xconfigAddMode(mode, "1280x1024");
- mode = xconfigAddMode(mode, "1600x1200");
+ mode = xconfigAddMode(mode, "nvidia-auto-select");
display = nvalloc(sizeof(XConfigDisplayRec));
display->depth = screen->defaultdepth;
diff --git a/multiple_screens.c b/multiple_screens.c
index dd8d60d..a8f6acb 100644
--- a/multiple_screens.c
+++ b/multiple_screens.c
@@ -77,9 +77,9 @@ int apply_multi_screen_options(Options *op, XConfigPtr config,
if (GET_BOOL_OPTION(op->boolean_options,
- SEPARATE_X_SCREENS_OPTION)) {
+ SEPARATE_X_SCREENS_BOOL_OPTION)) {
if (GET_BOOL_OPTION(op->boolean_option_values,
- SEPARATE_X_SCREENS_OPTION)) {
+ 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;
@@ -87,9 +87,9 @@ int apply_multi_screen_options(Options *op, XConfigPtr config,
}
if (GET_BOOL_OPTION(op->boolean_options,
- XINERAMA_OPTION)) {
+ XINERAMA_BOOL_OPTION)) {
if (!set_xinerama(GET_BOOL_OPTION(op->boolean_option_values,
- XINERAMA_OPTION),
+ XINERAMA_BOOL_OPTION),
config)) return FALSE;
}
@@ -403,7 +403,7 @@ static int enable_separate_x_screens(Options *op, XConfigPtr config,
}
for (i = 0; i < nscreens; i++) {
- if (i > pDevices->nDevices) {
+ if (i >= pDevices->nDevices) {
/*
* we have more screens than GPUs, this screen is no
* longer a candidate
@@ -457,6 +457,7 @@ static int enable_separate_x_screens(Options *op, XConfigPtr config,
&bus1, &slot1, &scratch)) continue;
if ((bus0 == bus1) && (slot0 == slot1)) {
screenlist[i] = NULL; /* no longer a candidate */
+ break;
}
}
}
@@ -468,7 +469,13 @@ static int enable_separate_x_screens(Options *op, XConfigPtr config,
clone_screen(screenlist[i]);
}
- /* wipe the existing adjacencies and recreate them */
+ /*
+ * wipe the existing adjacencies and recreate them
+ *
+ * XXX we should really only use the screens in the current
+ * adjacency list, plus the new cloned screens, when building the
+ * new adjacencies
+ */
xconfigFreeAdjacencyList(layout->adjacencies);
layout->adjacencies = NULL;
diff --git a/nvgetopt.c b/nvgetopt.c
index 13bc364..a0dfeea 100644
--- a/nvgetopt.c
+++ b/nvgetopt.c
@@ -23,8 +23,7 @@
*
*
* nvgetopt.c - portable getopt_long() replacement; removes the need
- * for the stupid optstring argument. Also adds support for the
- * "-feature"/"+feature" syntax.
+ * for the stupid optstring argument.
*/
#include <stdio.h>
@@ -50,10 +49,11 @@
*/
int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
- char **strval, int *boolval, int *intval)
+ char **strval, int *boolval, int *intval, int *disable_val)
{
char *c, *a, *arg, *name = NULL, *argument=NULL;
int i, found = NVGETOPT_FALSE, ret = 0, val = NVGETOPT_FALSE;
+ int disable = NVGETOPT_FALSE;
const NVGetoptOption *o = NULL;
static int argv_index = 0;
@@ -183,81 +183,72 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
fprintf(stderr, "%s: unrecognized option: \"%s\"\n", argv[0], arg);
goto done;
}
-
+
+
+ /* if the option is boolean, record 'val' as the boolean value */
+
if (o->flags & NVGETOPT_IS_BOOLEAN) {
-
- /* assign boolval */
-
if (boolval) *boolval = val;
}
-
-
+
+
/*
- * if this option takes an integer argument, then let the "--no-"
- * prefix set the integer argument to -2 (remove option from x config).
- * Otherwise, get the string argument and interpret it as an integer.
+ * 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_IS_INTEGER) {
-
- if (val == NVGETOPT_FALSE) {
- if (intval) {
- *intval = -2;
- }
- } else {
- if (argument) {
- if (!argument[0]) {
- fprintf(stderr, "%s: option \"%s\" requires an "
- "argument.\n", argv[0], arg);
- goto 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 (intval) {
- 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;
- }
- }
- }
-
+ if ((o->flags & NVGETOPT_ALLOW_DISABLE) && (val == NVGETOPT_FALSE)) {
+ disable = NVGETOPT_TRUE;
+ }
+
+
/*
- * if this option takes an argument, 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 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[]
*/
-
- } else if (o->flags & NVGETOPT_HAS_ARGUMENT) {
+
+ if ((o->flags & NVGETOPT_HAS_ARGUMENT) && !disable) {
if (argument) {
if (!argument[0]) {
- fprintf(stderr, "%s: option \"%s\" requires an argument.\n",
- argv[0], arg);
+ fprintf(stderr, "%s: option \"%s\" requires an "
+ "argument.\n", argv[0], arg);
goto done;
}
- if (strval) *strval = strdup(argument);
} else {
argv_index++;
if (argv_index >= argc) {
- fprintf(stderr, "%s: option \"%s\" requires an argument.\n",
- argv[0], arg);
+ fprintf(stderr, "%s: option \"%s\" requires an "
+ "argument.\n", argv[0], arg);
goto done;
}
- if (strval) *strval = argv[argv_index];
- }
+ argument = argv[argv_index];
+ }
+
+ /* argument is now a valid string: parse it */
+
+ if ((o->flags & NVGETOPT_INTEGER_ARGUMENT) && (intval)) {
+ 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)) {
+ *strval = strdup(argument);
+ } 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",
@@ -270,6 +261,8 @@ int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
done:
+ if (disable_val) *disable_val = disable;
+
free(arg);
return ret;
diff --git a/nvgetopt.h b/nvgetopt.h
index 135bc99..da29561 100644
--- a/nvgetopt.h
+++ b/nvgetopt.h
@@ -31,18 +31,61 @@
#define NVGETOPT_FALSE 0
#define NVGETOPT_TRUE 1
-#define NVGETOPT_HAS_ARGUMENT 0x1
-#define NVGETOPT_IS_BOOLEAN 0x2
-#define NVGETOPT_IS_INTEGER 0x4
+
+/*
+ * indicates that the option is a boolean value; the presence of the
+ * option will be interpretted as a TRUE value; if the option is
+ * prepended with '--no-', the option will be interpretted as a FALSE
+ * value. On success, nvgetopt will return the parsed boolean value
+ * through 'boolval'.
+ */
+
+#define NVGETOPT_IS_BOOLEAN 0x1
+
+
+/*
+ * indicates that the option takes an argument to be interpretted as a
+ * string; on success, nvgetopt will return the parsed string argument
+ * through 'strval'.
+ */
+
+#define NVGETOPT_STRING_ARGUMENT 0x2
+
+
+/*
+ * indicates that the option takes an argument to be interpretted as
+ * an integer; on success, nvgetopt will return the parsed integer
+ * argument through 'intval'.
+ */
+
+#define NVGETOPT_INTEGER_ARGUMENT 0x4
+
+
+/*
+ * 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 0x8
+
+
+#define NVGETOPT_HAS_ARGUMENT (NVGETOPT_STRING_ARGUMENT | \
+ NVGETOPT_INTEGER_ARGUMENT)
typedef struct {
const char *name;
int val;
unsigned int flags;
+ char *arg_name; /* not used by nvgetopt() */
char *description; /* not used by nvgetopt() */
} NVGetoptOption;
int nvgetopt(int argc, char *argv[], const NVGetoptOption *options,
- char **strval, int *boolval, int *intval);
+ char **strval, int *boolval, int *intval, int *disable_val);
#endif /* __NVGETOPT_H__ */
diff --git a/nvidia-xconfig.c b/nvidia-xconfig.c
index 8e78d6a..a810d4c 100644
--- a/nvidia-xconfig.c
+++ b/nvidia-xconfig.c
@@ -120,7 +120,7 @@ static char *cook_description(const char *description)
static void print_help(int advanced)
{
int i, j, len;
- char *msg, *tmp, scratch[64];
+ char *msg, *tmp, scratch[8], arg[64];
const NVGetoptOption *o;
print_version();
@@ -140,23 +140,41 @@ static void print_help(int advanced)
if (!advanced && !(o->flags & OPTION_HELP_ALWAYS)) continue;
+ /* if we are going to need the argument, process it now */
+
+ if (o->flags & NVGETOPT_HAS_ARGUMENT) {
+ if (o->arg_name) {
+ strcpy(arg, o->arg_name);
+ } else {
+ len = strlen(o->name);
+ for (j = 0; j < len; j++) arg[j] = toupper(o->name[j]);
+ arg[len] = '\0';
+ }
+ }
+
+ msg = nvstrcat("--", o->name, NULL);
+
if (isalpha(o->val)) {
sprintf(scratch, "%c", o->val);
- msg = nvstrcat("-", scratch, ", --", o->name, NULL);
- } else {
- msg = nvstrcat("--", o->name, NULL);
+
+ if (o->flags & NVGETOPT_HAS_ARGUMENT) {
+ tmp = nvstrcat("-", scratch, " ", arg, ", ", msg, NULL);
+ } else {
+ tmp = nvstrcat("-", scratch, ", ", msg, NULL);
+ }
+ free(msg);
+ msg = tmp;
}
+
if (o->flags & NVGETOPT_HAS_ARGUMENT) {
- len = strlen(o->name);
- for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]);
- scratch[len] = '\0';
- tmp = nvstrcat(msg, "=", scratch, NULL);
+ tmp = nvstrcat(msg, "=", arg, NULL);
free(msg);
msg = tmp;
}
- if (o->flags & NVGETOPT_IS_BOOLEAN ||
- o->flags & NVGETOPT_IS_INTEGER) {
- tmp = nvstrcat(msg, "/--no-", o->name, NULL);
+ if (((o->flags & NVGETOPT_IS_BOOLEAN) &&
+ !(o->flags & NVGETOPT_HAS_ARGUMENT)) ||
+ (o->flags & NVGETOPT_ALLOW_DISABLE)) {
+ tmp = nvstrcat(msg, ", --no-", o->name, NULL);
free(msg);
msg = tmp;
}
@@ -218,37 +236,37 @@ Options *parse_commandline(int argc, char *argv[])
int c, boolval;
u32 bit;
char *strval;
- int intval;
+ int intval, disable;
op = (Options *) nvalloc(sizeof(Options));
op->gop.x_project_root = get_default_project_root();
op->nvagp = -1;
- op->digital_vibrance = -1;
op->transparent_index = -1;
op->stereo = -1;
while (1) {
- c = nvgetopt(argc, argv, __options, &strval, &boolval, &intval);
+ c = nvgetopt(argc, argv, __options, &strval,
+ &boolval, &intval, &disable);
if (c == -1)
break;
/* catch the boolean options */
- if ((c >= XCONFIG_OPTION_START) &&
- (c <= (XCONFIG_OPTION_START + XCONFIG_BOOL_OPTION_COUNT))) {
+ if ((c >= XCONFIG_BOOL_OPTION_START) &&
+ (c <= (XCONFIG_BOOL_OPTION_START + XCONFIG_BOOL_OPTION_COUNT))) {
- bit = GET_BOOL_OPTION_BIT(c - XCONFIG_OPTION_START);
+ bit = GET_BOOL_OPTION_BIT(c - XCONFIG_BOOL_OPTION_START);
GET_BOOL_OPTION_SLOT(op->boolean_options,
- c - XCONFIG_OPTION_START) |= bit;
+ c - XCONFIG_BOOL_OPTION_START) |= bit;
if (boolval) {
GET_BOOL_OPTION_SLOT(op->boolean_option_values,
- c - XCONFIG_OPTION_START) |= bit;
+ c - XCONFIG_BOOL_OPTION_START) |= bit;
} else {
GET_BOOL_OPTION_SLOT(op->boolean_option_values,
- c - XCONFIG_OPTION_START) &= ~bit;
+ c - XCONFIG_BOOL_OPTION_START) &= ~bit;
}
continue;
}
@@ -266,7 +284,7 @@ Options *parse_commandline(int argc, char *argv[])
case 'a': op->enable_all_gpus = TRUE; break;
case '1': op->only_one_screen = TRUE; break;
- case 'd': op->depth = atoi(strval);
+ case 'd': op->depth = intval;
if ((op->depth != 8) &&
(op->depth != 15) &&
(op->depth != 16) &&
@@ -295,6 +313,14 @@ Options *parse_commandline(int argc, char *argv[])
case FORCE_GENERATE_OPTION: op->force_generate = TRUE; break;
case NVAGP_OPTION:
+
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->nvagp = -2;
+ break;
+ }
+
if (strcasecmp(strval, "none") == 0) op->nvagp = 0;
else if (strcasecmp(strval, "nvagp") == 0) op->nvagp = 1;
else if (strcasecmp(strval, "agpgart") == 0) op->nvagp = 2;
@@ -311,18 +337,16 @@ Options *parse_commandline(int argc, char *argv[])
}
break;
- case DIGITAL_VIBRANCE_OPTION:
- if ( intval != -2 && (intval < 0 || intval > 255) ) {
- fprintf(stderr, "\n");
- fprintf(stderr, "Invalid digital vibrance: %d.\n", intval);
- fprintf(stderr, "\n");
- goto fail;
+ case TRANSPARENT_INDEX_OPTION:
+
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->transparent_index = -2;
+ break;
}
- op->digital_vibrance = intval;
- break;
- case TRANSPARENT_INDEX_OPTION:
- if ( intval != -2 && (intval < 0 || intval > 255) ) {
+ if (intval < 0 || intval > 255) {
fprintf(stderr, "\n");
fprintf(stderr, "Invalid transparent index: %d.\n", intval);
fprintf(stderr, "\n");
@@ -332,7 +356,15 @@ Options *parse_commandline(int argc, char *argv[])
break;
case STEREO_OPTION:
- if ( intval != -2 && (intval < 1 || intval > 6) ) {
+
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->stereo = -2;
+ break;
+ }
+
+ if (intval < 1 || intval > 6) {
fprintf(stderr, "\n");
fprintf(stderr, "Invalid stereo: %d.\n", intval);
fprintf(stderr, "\n");
@@ -351,6 +383,51 @@ Options *parse_commandline(int argc, char *argv[])
}
break;
+ case REMOVE_MODE_OPTION:
+ nv_text_rows_append(&op->remove_modes, strval);
+ break;
+
+ case MULTI_GPU_OPTION:
+ {
+ const char* valid_values[] = {
+ "0",
+ "no",
+ "off",
+ "false",
+ "single",
+ "1",
+ "yes",
+ "on",
+ "true",
+ "auto",
+ "afr",
+ "sfr",
+ "aa",
+ NULL
+ };
+ int i;
+
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->multigpu = NV_DISABLE_STRING_OPTION;
+ break;
+ }
+
+ for (i = 0; valid_values[i]; i++) {
+ if (!strcasecmp(strval, valid_values[i]))
+ break;
+ }
+
+ if (valid_values[i]) {
+ op->multigpu = strval;
+ } else {
+ fprintf(stderr, "Invalid MultiGPU option: %s.\n", strval);
+ goto fail;
+ }
+ }
+ break;
+
case SLI_OPTION:
{
const char* valid_values[] = {
@@ -366,11 +443,19 @@ Options *parse_commandline(int argc, char *argv[])
"auto",
"afr",
"sfr",
- "sliaa",
+ "aa",
+ "afrofaa",
NULL
};
int i;
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->sli = NV_DISABLE_STRING_OPTION;
+ break;
+ }
+
for (i = 0; valid_values[i]; i++) {
if (!strcasecmp(strval, valid_values[i]))
break;
@@ -401,6 +486,13 @@ Options *parse_commandline(int argc, char *argv[])
};
int i;
+ /* mark as disabled, so we can remove the option later */
+
+ if (disable) {
+ op->rotate = NV_DISABLE_STRING_OPTION;
+ break;
+ }
+
for (i = 0; valid_values[i]; i++) {
if (!strcasecmp(strval, valid_values[i]))
break;
@@ -419,6 +511,74 @@ Options *parse_commandline(int argc, char *argv[])
case QUERY_GPU_INFO_OPTION: op->query_gpu_info = TRUE; break;
+ case 'E':
+ op->extract_edids_from_log = strval;
+ break;
+
+ case EXTRACT_EDIDS_OUTPUT_FILE_OPTION:
+ op->extract_edids_output_file = strval;
+ break;
+
+ case TWINVIEW_XINERAMA_INFO_ORDER_OPTION:
+ op->twinview_xinerama_info_order =
+ disable ? NV_DISABLE_STRING_OPTION : strval;
+ break;
+
+ case TWINVIEW_ORIENTATION_OPTION:
+ {
+ const char* valid_values[] = {
+ "RightOf",
+ "LeftOf",
+ "Above",
+ "Below",
+ "Clone",
+ NULL
+ };
+ int i;
+
+ if (disable) {
+ op->twinview_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 TwinViewOrientation option: "
+ "\"%s\".\n", strval);
+ goto fail;
+ }
+
+ op->twinview_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;
+ }
+
default:
goto fail;
}
@@ -701,7 +861,7 @@ static XConfigPtr find_system_xconfig(Options *op)
/* Read the opened X config file */
- error = xconfigReadConfigFile(op->screen, &config);
+ error = xconfigReadConfigFile(&config);
if (error != XCONFIG_RETURN_SUCCESS) {
xconfigCloseConfigFile();
return NULL;;
@@ -711,6 +871,13 @@ static XConfigPtr find_system_xconfig(Options *op)
xconfigCloseConfigFile();
+ /* Sanitize the X config file */
+
+ if (!xconfigSanitizeConfig(config, op->screen, &(op->gop))) {
+ xconfigFreeConfig(config);
+ return NULL;
+ }
+
return config;
} /* find_system_xconfig() */
@@ -730,12 +897,6 @@ int update_xconfig(Options *op, XConfigPtr config)
return FALSE;
}
- /* make sure the layout has the needed input devices */
-
- if (!xconfigCheckCoreInputDevices(config, layout)) {
- return FALSE;
- }
-
/* apply multi-display options */
if (!apply_multi_screen_options(op, config, layout)) {
@@ -872,6 +1033,11 @@ int main(int argc, char *argv[])
return (ret ? 0 : 1);
}
+ if (op->extract_edids_from_log) {
+ ret = extract_edids(op);
+ return (ret ? 0 : 1);
+ }
+
/*
* we want to open and parse the system's existing X config file,
* if possible
diff --git a/nvidia-xconfig.h b/nvidia-xconfig.h
index 2d839e6..593944d 100644
--- a/nvidia-xconfig.h
+++ b/nvidia-xconfig.h
@@ -52,37 +52,44 @@ typedef struct {
/* Boolean options */
-#define NOLOGO_OPTION 0
-#define UBB_OPTION 1
-#define RENDER_ACCEL_OPTION 2
-#define NO_RENDER_EXTENSION_OPTION 3
-#define OVERLAY_OPTION 4
-#define CIOVERLAY_OPTION 5
-#define OVERLAY_DEFAULT_VISUAL_OPTION 6
-#define NO_BANDWIDTH_TEST_OPTION 7
-#define NO_POWER_CONNECTOR_CHECK_OPTION 8
-#define ALLOW_DFP_STEREO_OPTION 9
-#define ALLOW_GLX_WITH_COMPOSITE_OPTION 10
-#define RANDR_ROTATION_OPTION 11
-#define TWINVIEW_OPTION 12
-#define SEPARATE_X_SCREENS_OPTION 13
-#define XINERAMA_OPTION 14
-#define NO_TWINVIEW_XINERAMA_INFO_OPTION 15
-#define NOFLIP_OPTION 16
-#define DAC_8BIT_OPTION 17
-#define USE_EDID_FREQS_OPTION 18
-#define IGNORE_EDID_OPTION 19
-#define USE_INT10_MODULE_OPTION 20
-#define FORCE_STEREO_FLIPPING_OPTION 21
-#define MULTISAMPLE_COMPATIBILITY_OPTION 22
-#define XVMC_USES_TEXTURES_OPTION 23
-#define EXACT_MODE_TIMINGS_DVI_OPTION 24
-#define ALLOW_DDCCI_OPTION 25
-#define LOAD_KERNEL_MODULE_OPTION 26
-#define ADD_ARGB_GLX_VISUALS_OPTION 27
-#define COMPOSITE_OPTION 28
-
-#define XCONFIG_BOOL_OPTION_COUNT (COMPOSITE_OPTION + 1)
+#define NOLOGO_BOOL_OPTION 0
+#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_BANDWIDTH_TEST_BOOL_OPTION 7
+#define NO_POWER_CONNECTOR_CHECK_BOOL_OPTION 8
+#define ALLOW_DFP_STEREO_BOOL_OPTION 9
+#define ALLOW_GLX_WITH_COMPOSITE_BOOL_OPTION 10
+#define RANDR_ROTATION_BOOL_OPTION 11
+#define TWINVIEW_BOOL_OPTION 12
+#define SEPARATE_X_SCREENS_BOOL_OPTION 13
+#define XINERAMA_BOOL_OPTION 14
+#define NO_TWINVIEW_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 USE_INT10_MODULE_BOOL_OPTION 20
+#define FORCE_STEREO_FLIPPING_BOOL_OPTION 21
+#define MULTISAMPLE_COMPATIBILITY_BOOL_OPTION 22
+#define XVMC_USES_TEXTURES_BOOL_OPTION 23
+#define EXACT_MODE_TIMINGS_DVI_BOOL_OPTION 24
+#define ALLOW_DDCCI_BOOL_OPTION 25
+#define LOAD_KERNEL_MODULE_BOOL_OPTION 26
+#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 DYNAMIC_TWINVIEW_BOOL_OPTION 34
+#define INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION 35
+
+#define XCONFIG_BOOL_OPTION_COUNT (INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION + 1)
/* # of 32-bit variables needed to hold all the boolean options (bits) */
#define XCONFIG_BOOL_OPTION_SLOTS \
@@ -99,6 +106,10 @@ typedef struct {
(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;
@@ -127,7 +138,6 @@ typedef struct __options {
int depth;
int nvagp;
- int digital_vibrance;
int transparent_index;
int stereo;
@@ -135,10 +145,20 @@ typedef struct __options {
char *output_xconfig;
char *layout;
char *screen;
+ char *multigpu;
char *sli;
char *rotate;
char *nvidia_cfg_path;
+ char *extract_edids_from_log;
+ char *extract_edids_output_file;
+ char *twinview_xinerama_info_order;
+ char *twinview_orientation;
+
+ struct {
+ int x;
+ int y;
+ } virtual;
TextRows add_modes;
TextRows remove_modes;
@@ -232,5 +252,10 @@ int read_scf_depth(int *depth);
int query_gpu_info(Options *op);
+/* extract_edids.c */
+
+int extract_edids(Options *op);
+
+
#endif /* __NVIDIA_XCONFIG_H__ */
diff --git a/option_table.h b/option_table.h
index 148120a..41660d0 100644
--- a/option_table.h
+++ b/option_table.h
@@ -5,8 +5,7 @@
*
* shortname - this is the one character short option name
*
- * flags - bitmask; possible values are NVGETOPT_HAS_ARGUMENT and
- * NVGETOPT_IS_BOOLEAN
+ * flags - bitmask; see NVGETOPT_ constants in nvgetopt.h
*
* description - text for use by print_help() to describe the option
*/
@@ -21,21 +20,57 @@
#define FORCE_GENERATE_OPTION 9
#define MOUSE_LIST_OPTION 10
#define MODE_OPTION 11
-#define NVIDIA_CFG_PATH_OPTION 12
-#define NVAGP_OPTION 13
-#define SLI_OPTION 14
-#define DISABLE_SCF_OPTION 15
-#define DIGITAL_VIBRANCE_OPTION 16
+#define REMOVE_MODE_OPTION 12
+#define NVIDIA_CFG_PATH_OPTION 13
+#define NVAGP_OPTION 14
+#define SLI_OPTION 15
+#define DISABLE_SCF_OPTION 16
#define TRANSPARENT_INDEX_OPTION 17
#define STEREO_OPTION 18
#define ROTATE_OPTION 19
#define QUERY_GPU_INFO_OPTION 20
+#define EXTRACT_EDIDS_OUTPUT_FILE_OPTION 21
+#define MULTI_GPU_OPTION 22
+#define TWINVIEW_XINERAMA_INFO_ORDER_OPTION 23
+#define TWINVIEW_ORIENTATION_OPTION 24
+#define VIRTUAL_OPTION 25
+
+/*
+ * 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(<your-new-constant>)
+ *
+ * 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
-#define XCONFIG_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))
/*
* The OPTION_HELP_ALWAYS flag is or'ed into the nvgetopts flags, but
- * is used by print_help() to know whether to print the help
+ * is only used by print_help() to know whether to print the help
* information for that option all the time, or only when advanced
* help is requested.
*/
@@ -45,92 +80,141 @@
static const NVGetoptOption __options[] = {
/* These options are printed by "nvidia-xconfig --help" */
- { "xconfig", 'c', NVGETOPT_HAS_ARGUMENT | OPTION_HELP_ALWAYS,
+ { "xconfig", 'c', NVGETOPT_STRING_ARGUMENT | OPTION_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_HAS_ARGUMENT | OPTION_HELP_ALWAYS,
+ { "output-xconfig", 'o',
+ NVGETOPT_STRING_ARGUMENT | OPTION_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 filename." },
+ "also be used as the output X configuration filename." },
- { "silent", 's', OPTION_HELP_ALWAYS,
+ { "silent", 's', OPTION_HELP_ALWAYS, NULL,
"Run silently; no messages will be printed to stdout, except for "
"warning and error messages to stderr." },
- { "tree", 't', OPTION_HELP_ALWAYS,
+ { "tree", 't', OPTION_HELP_ALWAYS, NULL,
"Read the X configuration file, print to stdout the X "
"configuration data in a tree format, and exit." },
- { "version", 'v', OPTION_HELP_ALWAYS,
+ { "version", 'v', OPTION_HELP_ALWAYS, NULL,
"Print the nvidia-xconfig version and exit." },
- { "help", 'h', OPTION_HELP_ALWAYS, "Print usage information for the "
- "common commandline options and exit." },
+ { "help", 'h', OPTION_HELP_ALWAYS, NULL,
+ "Print usage information for the common commandline options and exit." },
- { "advanced-help", 'A', OPTION_HELP_ALWAYS, "Print usage information "
- "for the common commandline options as well as the advanced options, "
- "and then exit." },
+ { "advanced-help", 'A', OPTION_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" */
{ "add-argb-glx-visuals",
- XCONFIG_OPTION_START + ADD_ARGB_GLX_VISUALS_OPTION, NVGETOPT_IS_BOOLEAN,
+ 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-ddcci", XCONFIG_OPTION_START + ALLOW_DDCCI_OPTION,
- NVGETOPT_IS_BOOLEAN, "Enables or disables DDC/CI support in the "
+ { "allow-ddcci", XCONFIG_BOOL_VAL(ALLOW_DDCCI_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL, "Enables or disables DDC/CI support in the "
"NV-CONTROL X extension." },
- { "allow-dfp-stereo",
- XCONFIG_OPTION_START + ALLOW_DFP_STEREO_OPTION, NVGETOPT_IS_BOOLEAN,
+ { "allow-dfp-stereo", XCONFIG_BOOL_VAL(ALLOW_DFP_STEREO_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Enable or disable the \"AllowDFPStereo\" X configuration option." },
{ "allow-glx-with-composite",
- XCONFIG_OPTION_START + ALLOW_GLX_WITH_COMPOSITE_OPTION,
- NVGETOPT_IS_BOOLEAN, "Enable or disable the \"AllowGLXWithComposite\" "
- "X configuration option." },
+ XCONFIG_BOOL_VAL(ALLOW_GLX_WITH_COMPOSITE_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
+ "Enable or disable the \"AllowGLXWithComposite\" X configuration "
+ "option." },
- { "bandwidth-test",
- XCONFIG_OPTION_START + NO_BANDWIDTH_TEST_OPTION, NVGETOPT_IS_BOOLEAN,
+ { "bandwidth-test", XCONFIG_BOOL_VAL(NO_BANDWIDTH_TEST_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Disable or enable the \"NoBandWidthTest\" X configuration option." },
{ "composite",
- XCONFIG_OPTION_START + COMPOSITE_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(COMPOSITE_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL,
"Enable or disable the \"Composite\" X extension." },
- { "dac-8bit", XCONFIG_OPTION_START + DAC_8BIT_OPTION, NVGETOPT_IS_BOOLEAN,
+ { "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." },
+
+ { "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)." },
- { "ddc",
- XCONFIG_OPTION_START + IGNORE_EDID_OPTION, NVGETOPT_IS_BOOLEAN,
- "Synonym for \"ignore-edid\"" },
-
- { "depth", 'd', NVGETOPT_HAS_ARGUMENT,
+ { "depth", 'd', NVGETOPT_INTEGER_ARGUMENT, NULL,
"Set the default depth to [DEPTH]; valid values for [DEPTH] are "
"8, 15, 16 and 24." },
- { "digital-vibrance", DIGITAL_VIBRANCE_OPTION,
- NVGETOPT_IS_INTEGER | NVGETOPT_HAS_ARGUMENT,
- "Enables digital vibrance control. Valid values for "
- "[DIGITAL-VIBRANCE] are 0-255." },
+ { "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
- { "enable-all-gpus", 'a', 0,
+ { "dynamic-twinview", XCONFIG_BOOL_VAL(DYNAMIC_TWINVIEW_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
+ "Enable or disable support for dynamically configuring TwinView." },
+
+ { "enable-all-gpus", 'a', 0, NULL,
"Configure an X screen on every GPU in the system." },
{ "exact-mode-timings-dvi",
- XCONFIG_OPTION_START + EXACT_MODE_TIMINGS_DVI_OPTION,
- NVGETOPT_IS_BOOLEAN, "Forces the initialization of the X server with "
+ 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." },
- { "flip", XCONFIG_OPTION_START + NOFLIP_OPTION, NVGETOPT_IS_BOOLEAN,
+ { "extract-edids-from-log", 'E', NVGETOPT_STRING_ARGUMENT, "LOG",
+ "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 hexidecimal 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-log' 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)." },
+
+ { "flip", XCONFIG_BOOL_VAL(NOFLIP_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL,
"Enable or disable OpenGL flipping" },
- { "force-generate", FORCE_GENERATE_OPTION, 0,
+ { "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 "
@@ -139,24 +223,19 @@ static const NVGetoptOption __options[] = {
"X config file for the basis of anything that nvidia-xconfig creates." },
{ "force-stereo-flipping",
- XCONFIG_OPTION_START + FORCE_STEREO_FLIPPING_OPTION, NVGETOPT_IS_BOOLEAN,
+ 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." },
- { "ignore-edid",
- XCONFIG_OPTION_START + IGNORE_EDID_OPTION, NVGETOPT_IS_BOOLEAN,
- "Disable or enable probing of EDID (Extended Display Identification "
- "Data) from your monitor." },
-
- { "use-edid-freqs",
- XCONFIG_OPTION_START + USE_EDID_FREQS_OPTION, NVGETOPT_IS_BOOLEAN,
- "Allow or disallow the X server to use 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." },
+ { "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_HAS_ARGUMENT,
+ { "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 "
@@ -164,67 +243,73 @@ static const NVGetoptOption __options[] = {
"For a list of possible keyboard types, see the '--keyboard-list' "
"option." },
- { "keyboard-driver", KEYBOARD_DRIVER_OPTION, NVGETOPT_HAS_ARGUMENT,
+ { "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 "
+ "using an X.Org X server, use 'kdb'; if you are using an XFree86 X "
"server, use 'keyboard'." },
- { "keyboard-list", KEYBOARD_LIST_OPTION, 0,
+ { "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_HAS_ARGUMENT,
+ { "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." },
- { "screen", SCREEN_OPTION, NVGETOPT_HAS_ARGUMENT,
- "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." },
-
{ "load-kernel-module",
- XCONFIG_OPTION_START + LOAD_KERNEL_MODULE_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(LOAD_KERNEL_MODULE_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Allow or disallow NVIDIA Linux X driver module to load the NVIDIA "
"Linux kernel module automatically."},
{ "logo",
- XCONFIG_OPTION_START + NOLOGO_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(NOLOGO_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL,
"Disable or enable the \"NoLogo\" X configuration option." },
- { "mode", MODE_OPTION, NVGETOPT_IS_BOOLEAN | NVGETOPT_HAS_ARGUMENT,
- "Adds or removes the specified mode from the mode list." },
+ { "mode",
+ MODE_OPTION, NVGETOPT_IS_BOOLEAN | NVGETOPT_STRING_ARGUMENT, NULL,
+ "Add the specified mode to the mode list." },
+
+ { "remove-mode", REMOVE_MODE_OPTION, NVGETOPT_STRING_ARGUMENT, "MODE",
+ "Remove the specified mode from the mode list." },
- { "mouse", MOUSE_OPTION, NVGETOPT_HAS_ARGUMENT,
+ { "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,
+ { "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', "
+ " 'Auto', 'AFR', 'SFR', 'AA'." },
+
{ "multisample-compatibility",
- XCONFIG_OPTION_START + MULTISAMPLE_COMPATIBILITY_OPTION,
- NVGETOPT_IS_BOOLEAN, "Enable or disable the use of separate front and "
+ XCONFIG_BOOL_VAL(MULTISAMPLE_COMPATIBILITY_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
+ "Enable or disable the use of separate front and "
"back multisample buffers." },
- { "nvagp", NVAGP_OPTION, NVGETOPT_HAS_ARGUMENT,
+ { "nvagp", NVAGP_OPTION,
+ NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL,
"Set the NvAGP X config option value. Possible values are 0 (no AGP), "
"1 (NVIDIA's AGP), 2 (AGPGART), 3 (try AGPGART, then try NVIDIA's AGP); "
"these values can also be specified as 'none', 'nvagp', 'agpgart', or "
"'any'." },
- { "nvidia-cfg-path", NVIDIA_CFG_PATH_OPTION, NVGETOPT_HAS_ARGUMENT,
+ { "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 "
@@ -236,24 +321,25 @@ static const NVGetoptOption __options[] = {
"Disable all but one X screen." },
{ "overlay",
- XCONFIG_OPTION_START + OVERLAY_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(OVERLAY_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL,
"Enable or disable the \"Overlay\" X configuration option." },
{ "cioverlay",
- XCONFIG_OPTION_START + CIOVERLAY_OPTION, NVGETOPT_IS_BOOLEAN,
+ 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_IS_INTEGER | NVGETOPT_HAS_ARGUMENT,
+ 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."},
- { "overlay-default-visual",
- XCONFIG_OPTION_START + OVERLAY_DEFAULT_VISUAL_OPTION,
- NVGETOPT_IS_BOOLEAN, "Enable or disable the \"OverlayDefaultVisual\" "
- "X configuration option." },
-
- { "post-tree", 'T', 0,
+ { "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. "
@@ -261,32 +347,49 @@ static const NVGetoptOption __options[] = {
"to stdout as a tree instead of writing the results to file." },
{ "power-connector-check",
- XCONFIG_OPTION_START + NO_POWER_CONNECTOR_CHECK_OPTION,
- NVGETOPT_IS_BOOLEAN, "Disable or enable the \"NoPowerConnectorCheck\" "
+ XCONFIG_BOOL_VAL(NO_POWER_CONNECTOR_CHECK_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
+ "Disable or enable the \"NoPowerConnectorCheck\" "
"X configuration option." },
- { "query-gpu-info", QUERY_GPU_INFO_OPTION, 0,
+ { "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." },
{ "randr-rotation",
- XCONFIG_OPTION_START + RANDR_ROTATION_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(RANDR_ROTATION_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL,
"Enable or disable the \"RandRRotation\" X configuration option." },
- { "rotate",
- ROTATE_OPTION, NVGETOPT_HAS_ARGUMENT,
- "Enable or disable the \"Rotate\" X configuration option. Valid values "
- "for [ROTATE] are 'normal', 'left', 'inverted', and 'right'." },
-
{ "render-accel",
- XCONFIG_OPTION_START + RENDER_ACCEL_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(RENDER_ACCEL_BOOL_OPTION), NVGETOPT_IS_BOOLEAN, NULL,
"Enable or disable the \"RenderAccel\" X configuration option." },
{ "render-extension",
- XCONFIG_OPTION_START + NO_RENDER_EXTENSION_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(NO_RENDER_EXTENSION_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Disable or enable the \"NoRenderExtension\" X configuration option." },
+ { "rotate",
+ ROTATE_OPTION, NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL,
+ "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 "
+ "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_OPTION_START + SEPARATE_X_SCREENS_OPTION, NVGETOPT_IS_BOOLEAN,
+ 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 TwinView, or as separate X screens. "
"When the '--separate-x-screens' option is specified, each GPU on which "
@@ -296,53 +399,93 @@ static const NVGetoptOption __options[] = {
"README description of \"Separate X Screens on One GPU\" for further "
"details." },
- { "sli", SLI_OPTION, NVGETOPT_HAS_ARGUMENT,
+ { "sli", SLI_OPTION,
+ NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL,
"Enable or disable SLI. Valid values for [SLI] are 'Off', 'Auto', "
- "'AFR', 'SFR', and 'SLIAA'." },
+ "'AFR', 'SFR', 'AA', 'AFRofAA'." },
- { "stereo", STEREO_OPTION, NVGETOPT_IS_INTEGER | NVGETOPT_HAS_ARGUMENT,
- "Enable/Disable the stereo mode. Valid values for [STEREO] are: 1 "
+ { "stereo", STEREO_OPTION,
+ NVGETOPT_INTEGER_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL,
+ "Enable or disable the stereo mode. Valid values for [STEREO] are: 1 "
"(DCC glasses), 2 (Blueline glasses), 3 (Onboard stereo), 4 (TwinView "
"clone mode stereo), 5 (SeeReal digital flat panel), 6 (Sharp3D "
"digital flat panel)." },
- { "twinview", XCONFIG_OPTION_START + TWINVIEW_OPTION, NVGETOPT_IS_BOOLEAN,
- "Enable or disable TwinView." },
+ { "twinview", XCONFIG_BOOL_VAL(TWINVIEW_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL, "Enable or disable TwinView." },
+ { "twinview-orientation", TWINVIEW_ORIENTATION_OPTION,
+ NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, "ORIENTATION",
+ "Specify the TwinViewOrientation. Valid values for [ORIENTATION] are: "
+ "\"RightOf\" (the default), \"LeftOf\", \"Above\", \"Below\", or "
+ "\"Clone\"." },
+
{ "twinview-xinerama-info",
- XCONFIG_OPTION_START + NO_TWINVIEW_XINERAMA_INFO_OPTION,
- NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(NO_TWINVIEW_XINERAMA_INFO_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Prohibits providing Xinerama information when in TwinView." },
+ { "twinview-xinerama-info-order",
+ TWINVIEW_XINERAMA_INFO_ORDER_OPTION,
+ NVGETOPT_STRING_ARGUMENT | NVGETOPT_ALLOW_DISABLE, NULL,
+ "Enable or disable the \"TwinViewXineramaInfoOrder\" X configuration "
+ "option. [TWINVIEW-XINERAMA-INFO-ORDER] is a comma-separated list "
+ "of display device names that describe the order in which "
+ "TwinViewXineramaInfo should be reported. E.g., \"CRT, DFP, TV\"." },
+
{ "ubb",
- XCONFIG_OPTION_START + UBB_OPTION, NVGETOPT_IS_BOOLEAN,
+ 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-int10-module",
- XCONFIG_OPTION_START + USE_INT10_MODULE_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(USE_INT10_MODULE_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Enable use of the X Int10 module to soft-boot all secondary cards, "
"rather than POSTing the cards through the NVIDIA kernel module." },
- { "x-prefix", X_PREFIX_OPTION, NVGETOPT_HAS_ARGUMENT,
+ { "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_OPTION_START + XINERAMA_OPTION, NVGETOPT_IS_BOOLEAN,
- "Enable or disable Xinerama." },
+ { "xinerama", XCONFIG_BOOL_VAL(XINERAMA_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL, "Enable or disable Xinerama." },
{ "xvmc-uses-textures",
- XCONFIG_OPTION_START + XVMC_USES_TEXTURES_OPTION, NVGETOPT_IS_BOOLEAN,
+ XCONFIG_BOOL_VAL(XVMC_USES_TEXTURES_BOOL_OPTION),
+ NVGETOPT_IS_BOOLEAN, NULL,
"Forces XvMC to use the 3D engine for XvMCPutSurface requests rather "
"than the video overlay." },
-#if defined(NV_SUNOS)
- { "disable-scf", DISABLE_SCF_OPTION, 0,
- "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
-
- { NULL, 0 , 0, NULL },
+ { NULL, 0, 0, NULL, NULL },
};
diff --git a/options.c b/options.c
index caf7e52..c5d561f 100644
--- a/options.c
+++ b/options.c
@@ -40,34 +40,41 @@ typedef struct {
static const NvidiaXConfigOption __options[] = {
- { NOLOGO_OPTION, TRUE, "NoLogo" },
- { UBB_OPTION, FALSE, "UBB" },
- { RENDER_ACCEL_OPTION, FALSE, "RenderAccel" },
- { NO_RENDER_EXTENSION_OPTION, TRUE, "NoRenderExtension" },
- { OVERLAY_OPTION, FALSE, "Overlay" },
- { CIOVERLAY_OPTION, FALSE, "CIOverlay" },
- { OVERLAY_DEFAULT_VISUAL_OPTION, FALSE, "OverlayDefaultVisual" },
- { NO_BANDWIDTH_TEST_OPTION, TRUE, "NoBandWidthTest" },
- { NO_POWER_CONNECTOR_CHECK_OPTION, TRUE, "NoPowerConnectorCheck" },
- { ALLOW_DFP_STEREO_OPTION, FALSE, "AllowDFPStereo" },
- { ALLOW_GLX_WITH_COMPOSITE_OPTION, FALSE, "AllowGLXWithComposite" },
- { RANDR_ROTATION_OPTION, FALSE, "RandRRotation" },
- { TWINVIEW_OPTION, FALSE, "TwinView" },
- { XINERAMA_OPTION, FALSE, "Xinerama" },
- { NO_TWINVIEW_XINERAMA_INFO_OPTION, TRUE, "NoTwinViewXineramaInfo" },
- { NOFLIP_OPTION, TRUE, "NoFlip" },
- { DAC_8BIT_OPTION, FALSE, "Dac8Bit" },
- { USE_EDID_FREQS_OPTION, FALSE, "UseEdidFreqs" },
- { IGNORE_EDID_OPTION, FALSE, "IgnoreEDID" },
- { USE_INT10_MODULE_OPTION, FALSE, "UseInt10Module" },
- { FORCE_STEREO_FLIPPING_OPTION, FALSE, "ForceStereoFlipping" },
- { MULTISAMPLE_COMPATIBILITY_OPTION, FALSE, "MultisampleCompatibility" },
- { XVMC_USES_TEXTURES_OPTION, FALSE, "XvmcUsesTextures" },
- { EXACT_MODE_TIMINGS_DVI_OPTION, FALSE, "ExactModeTimingsDVI" },
- { ALLOW_DDCCI_OPTION, FALSE, "AllowDDCCI" },
- { LOAD_KERNEL_MODULE_OPTION, FALSE, "LoadKernelModule" },
- { ADD_ARGB_GLX_VISUALS_OPTION, FALSE, "AddARGBGLXVisuals" },
- { 0, FALSE, NULL },
+ { NOLOGO_BOOL_OPTION, TRUE, "NoLogo" },
+ { 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_BANDWIDTH_TEST_BOOL_OPTION, TRUE, "NoBandWidthTest" },
+ { NO_POWER_CONNECTOR_CHECK_BOOL_OPTION, TRUE, "NoPowerConnectorCheck" },
+ { ALLOW_DFP_STEREO_BOOL_OPTION, FALSE, "AllowDFPStereo" },
+ { ALLOW_GLX_WITH_COMPOSITE_BOOL_OPTION, FALSE, "AllowGLXWithComposite" },
+ { RANDR_ROTATION_BOOL_OPTION, FALSE, "RandRRotation" },
+ { TWINVIEW_BOOL_OPTION, FALSE, "TwinView" },
+ { XINERAMA_BOOL_OPTION, FALSE, "Xinerama" },
+ { NO_TWINVIEW_XINERAMA_INFO_BOOL_OPTION, TRUE, "NoTwinViewXineramaInfo" },
+ { NOFLIP_BOOL_OPTION, TRUE, "NoFlip" },
+ { DAC_8BIT_BOOL_OPTION, FALSE, "Dac8Bit" },
+ { USE_EDID_FREQS_BOOL_OPTION, FALSE, "UseEdidFreqs" },
+ { USE_EDID_BOOL_OPTION, FALSE, "UseEdid" },
+ { USE_INT10_MODULE_BOOL_OPTION, FALSE, "UseInt10Module" },
+ { FORCE_STEREO_FLIPPING_BOOL_OPTION, FALSE, "ForceStereoFlipping" },
+ { MULTISAMPLE_COMPATIBILITY_BOOL_OPTION, FALSE, "MultisampleCompatibility" },
+ { XVMC_USES_TEXTURES_BOOL_OPTION, FALSE, "XvmcUsesTextures" },
+ { EXACT_MODE_TIMINGS_DVI_BOOL_OPTION, FALSE, "ExactModeTimingsDVI" },
+ { ALLOW_DDCCI_BOOL_OPTION, FALSE, "AllowDDCCI" },
+ { LOAD_KERNEL_MODULE_BOOL_OPTION, FALSE, "LoadKernelModule" },
+ { 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" },
+ { DYNAMIC_TWINVIEW_BOOL_OPTION, FALSE, "DynamicTwinView" },
+ { INCLUDE_IMPLICIT_METAMODES_BOOL_OPTION,FALSE, "IncludeImplicitMetaModes" },
+ { 0, FALSE, NULL },
};
@@ -118,8 +125,14 @@ static void remove_option(XConfigScreenPtr screen, const char *name)
{
XConfigDisplayPtr display;
- remove_option_from_list(&screen->device->options, name);
- remove_option_from_list(&screen->monitor->options, name);
+ if (!screen) return;
+
+ if (screen->device) {
+ remove_option_from_list(&screen->device->options, name);
+ }
+ if (screen->monitor) {
+ remove_option_from_list(&screen->monitor->options, name);
+ }
remove_option_from_list(&screen->options, name);
for (display = screen->displays; display; display = display->next) {
@@ -160,16 +173,15 @@ static void update_twinview_options(Options *op, XConfigScreenPtr screen)
* options, too
*/
- if (GET_BOOL_OPTION(op->boolean_options, TWINVIEW_OPTION)) {
- if (GET_BOOL_OPTION(op->boolean_option_values, TWINVIEW_OPTION)) {
- set_option_value(screen, "TwinViewOrientation", "RightOf");
- set_option_value(screen, "UseEdidFreqs", "True"); /* XXX */
- set_option_value(screen, "MetaModes", "1024x768, 1024x768");
- } else {
- remove_option(screen, "TwinViewOrientation");
- remove_option(screen, "SecondMonitorHorizSync");
- remove_option(screen, "SecondMonitorVertRefresh");
- remove_option(screen, "MetaModes");
+ if (GET_BOOL_OPTION(op->boolean_options, TWINVIEW_BOOL_OPTION)) {
+ remove_option(screen, "TwinViewOrientation");
+ remove_option(screen, "SecondMonitorHorizSync");
+ remove_option(screen, "SecondMonitorVertRefresh");
+ remove_option(screen, "MetaModes");
+
+ if (GET_BOOL_OPTION(op->boolean_option_values, TWINVIEW_BOOL_OPTION)) {
+ set_option_value(screen, "MetaModes",
+ "nvidia-auto-select, nvidia-auto-select");
}
}
} /* update_twinview_options() */
@@ -177,6 +189,54 @@ static void update_twinview_options(Options *op, XConfigScreenPtr screen)
/*
+ * 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++) {
+ display->modes = xconfigRemoveMode(display->modes,
+ op->remove_modes.t[i]);
+ }
+ for (i = 0; i < op->add_modes.n; i++) {
+ display->modes = xconfigAddMode(display->modes,
+ op->add_modes.t[i]);
+ }
+
+ /* 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.
*/
@@ -184,7 +244,6 @@ static void update_twinview_options(Options *op, XConfigScreenPtr screen)
void update_options(Options *op, XConfigScreenPtr screen)
{
int i;
- XConfigDisplayPtr display;
const NvidiaXConfigOption *o;
char *val;
char scratch[8];
@@ -195,13 +254,13 @@ void update_options(Options *op, XConfigScreenPtr screen)
if (GET_BOOL_OPTION(op->boolean_options, i)) {
/*
- * SEPARATE_X_SCREENS_OPTION, XINERAMA_OPTION, and
- * COMPOSITE_OPTION are handled separately
+ * SEPARATE_X_SCREENS_BOOL_OPTION, XINERAMA_BOOL_OPTION,
+ * and COMPOSITE_BOOL_OPTION are handled separately
*/
- if (i == SEPARATE_X_SCREENS_OPTION) continue;
- if (i == XINERAMA_OPTION) continue;
- if (i == COMPOSITE_OPTION) continue;
+ if (i == SEPARATE_X_SCREENS_BOOL_OPTION) continue;
+ if (i == XINERAMA_BOOL_OPTION) continue;
+ if (i == COMPOSITE_BOOL_OPTION) continue;
o = get_option(i);
@@ -226,26 +285,10 @@ void update_options(Options *op, XConfigScreenPtr screen)
update_twinview_options(op, screen);
- /* update the mode list, based on what we have on the commandline */
+ /* update the Display SubSection options */
- for (display = screen->displays; display; display = display->next) {
- for (i = 0; i < op->remove_modes.n; i++) {
- display->modes = xconfigRemoveMode(display->modes,
- op->remove_modes.t[i]);
- }
- for (i = 0; i < op->add_modes.n; i++) {
- display->modes = xconfigAddMode(display->modes,
- op->add_modes.t[i]);
- }
+ update_display_options(op, screen);
- /* XXX should we sort the mode list? */
-
- /*
- * XXX should we update the mode list with what we can get
- * through libnvidia-cfg?
- */
- }
-
/* add the nvagp option */
if (op->nvagp != -1) {
@@ -256,16 +299,6 @@ void update_options(Options *op, XConfigScreenPtr screen)
}
}
- /* add the digital vibrance option */
-
- if (op->digital_vibrance != -1) {
- remove_option(screen, "digitalvibrance");
- if (op->digital_vibrance != -2) {
- snprintf(scratch, 8, "%d", op->digital_vibrance);
- set_option_value(screen, "DigitalVibrance", scratch);
- }
- }
-
/* add the transparent index option */
if (op->transparent_index != -1) {
@@ -286,17 +319,51 @@ void update_options(Options *op, XConfigScreenPtr screen)
}
}
+ /* 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");
- set_option_value(screen, "SLI", op->sli);
+ if (op->sli != NV_DISABLE_STRING_OPTION) {
+ set_option_value(screen, "SLI", op->sli);
+ }
}
/* add the rotate option */
if (op->rotate) {
remove_option(screen, "Rotate");
- set_option_value(screen, "Rotate", op->rotate);
+ if (op->rotate != NV_DISABLE_STRING_OPTION) {
+ set_option_value(screen, "Rotate", op->rotate);
+ }
}
+
+ /* add the twinview xinerama info order option */
+
+ if (op->twinview_xinerama_info_order) {
+ remove_option(screen, "TwinViewXineramaInfoOrder");
+ if (op->twinview_xinerama_info_order != NV_DISABLE_STRING_OPTION) {
+ set_option_value(screen, "TwinViewXineramaInfoOrder",
+ op->twinview_xinerama_info_order);
+ }
+ }
+
+ /* add the twinview orientation option */
+
+ if (op->twinview_orientation) {
+ remove_option(screen, "TwinViewOrientation");
+ if (op->twinview_orientation != NV_DISABLE_STRING_OPTION) {
+ set_option_value(screen, "TwinViewOrientation",
+ op->twinview_orientation);
+ }
+ }
+
} /* update_options() */
diff --git a/tree.c b/tree.c
index e37a988..13ea6d2 100644
--- a/tree.c
+++ b/tree.c
@@ -179,6 +179,28 @@ static void print_modes(XConfigScreenPtr screen)
/*
+ * 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()
*/
@@ -195,7 +217,8 @@ static void print_screen(XConfigScreenPtr screen)
printf(" | |--> DefaultColorDepth %d\n",
screen->defaultdepth);
print_modes(screen);
-
+ print_virtual(screen);
+
printf(" |\n");
} /* print_screen() */