summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2009-01-08 18:54:01 -0800
committerAaron Plattner <aplattner@nvidia.com>2009-01-08 18:54:01 -0800
commitf6dccc8377d4ddf9255d05f959df6ee87089e609 (patch)
tree2bff91df4fa5597d7d2b984e3ec9204ac3250c9f
parent717b0fa99512da47c7e790281236fc8626e1dacd (diff)
-rw-r--r--src/XF86Config-parser/Generate.c156
-rw-r--r--src/XF86Config-parser/Screen.c62
-rw-r--r--src/XF86Config-parser/xf86Parser.h7
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c17
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 */