diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-13 10:26:53 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-13 10:26:53 -0800 |
commit | 519a7f3cc9b213e2d1e7c94b64bd0d68d16bb872 (patch) | |
tree | 46f743cd79dd85d8d16e5ba653f91526fbfd8183 | |
parent | 80e326c7dff56784314d3ae0087e914b23598a5a (diff) |
1.0-96261.0-9626
30 files changed, 1916 insertions, 595 deletions
@@ -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; @@ -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; @@ -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 }, }; @@ -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() */ @@ -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() */ |