diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2009-01-08 18:54:01 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2009-01-08 18:54:01 -0800 |
commit | f6dccc8377d4ddf9255d05f959df6ee87089e609 (patch) | |
tree | 2bff91df4fa5597d7d2b984e3ec9204ac3250c9f | |
parent | 717b0fa99512da47c7e790281236fc8626e1dacd (diff) |
-rw-r--r-- | src/XF86Config-parser/Generate.c | 156 | ||||
-rw-r--r-- | src/XF86Config-parser/Screen.c | 62 | ||||
-rw-r--r-- | src/XF86Config-parser/xf86Parser.h | 7 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig.c | 17 |
4 files changed, 231 insertions, 11 deletions
diff --git a/src/XF86Config-parser/Generate.c b/src/XF86Config-parser/Generate.c index a45602e..04bc2fb 100644 --- a/src/XF86Config-parser/Generate.c +++ b/src/XF86Config-parser/Generate.c @@ -140,9 +140,10 @@ XConfigScreenPtr xconfigGenerateAddScreen(XConfigPtr config, /* - * assign_screen_adjacencies() - setup all the adjacency information - * for the X screens in the given layout. Nothing fancy here: just - * position all the screens horizontally, moving from left to right. + * xconfigGenerateAssignScreenAdjacencies() - setup all the adjacency + * information for the X screens in the given layout. Nothing fancy + * here: just position all the screens horizontally, moving from left + * to right. */ void xconfigGenerateAssignScreenAdjacencies(XConfigLayoutPtr layout) @@ -1292,3 +1293,152 @@ int xconfigAddKeyboard(GenerateOptions *gop, XConfigPtr config) return TRUE; } /* xconfigAddKeyboard() */ + + + +/* + * xconfigGetDefaultProjectRoot() - scan some common directories for the X + * project root. + * + * Users of this information should be careful to account for the + * modular layout. + */ + +static char *xconfigGetDefaultProjectRoot(void) +{ + char *paths[] = { "/usr/X11R6", "/usr/X11", NULL }; + struct stat stat_buf; + int i; + + for (i = 0; paths[i]; i++) { + + if (stat(paths[i], &stat_buf) == -1) { + continue; + } + + if (S_ISDIR(stat_buf.st_mode)) { + return paths[i]; + } + } + + /* default to "/usr/X11R6", I guess */ + + return paths[0]; + +} /* xconfigGetDefaultProjectRoot() */ + + + +/* + * xconfigGetXServerInUse() - try to determine which X server is in use + * (XFree86, Xorg); also determine if the X server supports the + * Extension section of the X config file; support for the "Extension" + * section was added between X.Org 6.7 and 6.8. + * + * Some of the parsing here mimics what is done in the + * check_for_modular_xorg() function in nvidia-installer + */ + +#define NV_LINE_LEN 1024 +#define EXTRA_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/bin/X11" +#define VERSION_FORMAT "X Protocol Version %d, Revision %d, Release %d.%d" + +void xconfigGetXServerInUse(GenerateOptions *gop) +{ +#if defined(NV_SUNOS) + + /* + * Solaris x86/x64 always uses X.Org 6.8 or higher, atleast as far + * as the NVIDIA X driver is concerned + */ + + gop->xserver = X_IS_XORG; + gop->supports_extension_section = TRUE; + +#else + + FILE *stream = NULL; + int xserver = -1; + int dummy, len, release_major, release_minor; + char *cmd, *ptr, *ret; + + gop->supports_extension_section = FALSE; + + /* run `X -version` with a PATH that hopefully includes the X binary */ + + cmd = xconfigStrcat("PATH=", gop->x_project_root, ":", + EXTRA_PATH, ":$PATH X -version 2>&1", NULL); + + if ((stream = popen(cmd, "r"))) { + char buf[NV_LINE_LEN]; + + /* read in as much of the input as we can fit into the buffer */ + + ptr = buf; + + do { + len = NV_LINE_LEN - (ptr - buf) - 1; + ret = fgets(ptr, len, stream); + ptr = strchr(ptr, '\0'); + } while ((ret != NULL) && (len > 1)); + + /* Check if this is an XFree86 release */ + + if (strstr(buf, "XFree86 Version") != NULL) { + xserver = X_IS_XF86; + gop->supports_extension_section = FALSE; + } else { + xserver = X_IS_XORG; + if ((ptr = strstr(buf, "X Protocol Version")) != NULL && + sscanf(ptr, VERSION_FORMAT, &dummy, &dummy, + &release_major, &release_minor) == 4) { + + if ((release_major > 6) || + ((release_major == 6) && (release_minor >= 8))) { + gop->supports_extension_section = TRUE; + } + } + } + } + /* Close the popen()'ed stream. */ + pclose(stream); + free(cmd); + + if (xserver == -1) { + char *xorgpath; + + xorgpath = xconfigStrcat(gop->x_project_root, "/bin/Xorg", NULL); + if (access(xorgpath, F_OK)==0) { + xserver = X_IS_XORG; + } else { + xserver = X_IS_XF86; + } + free(xorgpath); + } + + gop->xserver=xserver; +#endif + +} /* xconfigGetXServerInUse() */ + + + +/* + * xconfigGenerateLoadDefaultOptions - initialize a GenerateOptions + * structure with default values by peeking at the file system. + */ + +void xconfigGenerateLoadDefaultOptions(GenerateOptions *gop) +{ + memset(gop, 0, sizeof(GenerateOptions)); + + gop->x_project_root = xconfigGetDefaultProjectRoot(); + + /* XXX What to default the following to? + gop->xserver + gop->keyboard + gop->mouse + gop->keyboard_driver + */ + +} /* xconfigGenerateLoadDefaultOptions() */ diff --git a/src/XF86Config-parser/Screen.c b/src/XF86Config-parser/Screen.c index fbb155c..ce6b299 100644 --- a/src/XF86Config-parser/Screen.c +++ b/src/XF86Config-parser/Screen.c @@ -79,6 +79,8 @@ static XConfigSymTabRec DisplayTab[] = #define CLEANUP xconfigFreeDisplayList +static int addImpliedScreen(XConfigPtr config); + XConfigDisplayPtr xconfigParseDisplaySubSection (void) { @@ -500,12 +502,12 @@ xconfigValidateScreen (XConfigPtr p) XConfigDevicePtr device; XConfigAdaptorLinkPtr adaptor; - if (!screen) - { - xconfigErrorMsg(ValidationErrorMsg, "At least one Screen section " - "is required."); - return (FALSE); - } + /* + * if we do not have a screen, just return TRUE; we'll add a + * screen later during the Sanitize step + */ + + if (!screen) return TRUE; while (screen) { @@ -569,6 +571,10 @@ int xconfigSanitizeScreen(XConfigPtr p) { XConfigScreenPtr screen = p->screens; XConfigMonitorPtr monitor; + + if (!addImpliedScreen(p)) { + return FALSE; + } while (screen) { @@ -610,8 +616,9 @@ int xconfigSanitizeScreen(XConfigPtr p) screen->monitor_name = xconfigStrdup(monitor->identifier); - if (!xconfigValidateMonitor(p, screen)) - return (FALSE); + if (!xconfigValidateMonitor(p, screen)) { + return FALSE; + } } } @@ -685,4 +692,43 @@ xconfigRemoveMode(XConfigModePtr *pHead, const char *name) } +static int addImpliedScreen(XConfigPtr config) +{ + XConfigScreenPtr screen; + XConfigDevicePtr device; + XConfigMonitorPtr monitor; + if (config->screens) return TRUE; + + xconfigErrorMsg(WarnMsg, "No Screen specified, constructing implicit " + "screen section.\n"); + + /* allocate the new screen section */ + + screen = calloc(1, sizeof(XConfigScreenRec)); + if (!screen) return FALSE; + + screen->identifier = xconfigStrdup("Default Screen"); + + /* + * Use the first device section if there is one. + */ + if (config->devices) { + device = config->devices; + screen->device_name = xconfigStrdup(device->identifier); + screen->device = device; + } + + /* + * Use the first monitor section if there is one. + */ + if (config->monitors) { + monitor = config->monitors; + screen->monitor_name = xconfigStrdup(monitor->identifier); + screen->monitor = monitor; + } + + config->screens = screen; + + return TRUE; +} diff --git a/src/XF86Config-parser/xf86Parser.h b/src/XF86Config-parser/xf86Parser.h index 7d34407..f8a5f0f 100644 --- a/src/XF86Config-parser/xf86Parser.h +++ b/src/XF86Config-parser/xf86Parser.h @@ -591,6 +591,9 @@ typedef struct { char *keyboard; char *mouse; char *keyboard_driver; + + int supports_extension_section; + } GenerateOptions; @@ -720,6 +723,10 @@ void xconfigGenerateAssignScreenAdjacencies(XConfigLayoutPtr layout); void xconfigGeneratePrintPossibleMice(void); void xconfigGeneratePrintPossibleKeyboards(void); +void xconfigGenerateLoadDefaultOptions(GenerateOptions *gop); + +void xconfigGetXServerInUse(GenerateOptions *gop); + /* * check (and update, if necessary) the inputs in the specified layout diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c index c7f88b0..9403fe6 100644 --- a/src/gtk+-2.x/ctkdisplayconfig.c +++ b/src/gtk+-2.x/ctkdisplayconfig.c @@ -6584,6 +6584,7 @@ static gboolean update_xconfig_save_buffer(CtkDisplayConfig *ctk_object) mergable = FALSE; } else { + GenerateOptions gop; /* Must be able to parse the file as an X config file */ error = xconfigReadConfigFile(&mergeConfig); @@ -6603,6 +6604,22 @@ static gboolean update_xconfig_save_buffer(CtkDisplayConfig *ctk_object) mergeConfig = NULL; mergable = FALSE; } + + /* Sanitize the X config file */ + xconfigGenerateLoadDefaultOptions(&gop); + xconfigGetXServerInUse(&gop); + + if (!xconfigSanitizeConfig(mergeConfig, NULL, &gop)) { + gchar *msg = g_strdup_printf("Failed to sanitize existing X " + "config file '%s'!", + filename); + ctk_display_warning_msg + (ctk_get_parent_window(GTK_WIDGET(ctk_object)), msg); + g_free(msg); + + xconfigFreeConfig(&mergeConfig); + mergable = FALSE; + } } /* If we're not actualy doing a merge, close the file */ |