summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2008-02-12 21:29:01 -0800
committerAaron Plattner <aplattner@nvidia.com>2008-02-12 21:29:01 -0800
commit9d2899dd01e78209d5a6f0428bd52c22a9245b48 (patch)
treeb3e7b68731fc01e723c2c102391e19e36fc09680
parentf984a7a8a1e090275f54c8c5ba33d30950a0c1f6 (diff)
169.07169.07
-rw-r--r--src/XF86Config-parser/Scan.c12
-rw-r--r--src/config-file.c65
-rw-r--r--src/config-file.h8
-rw-r--r--src/gtk+-2.x/ctkconfig.c164
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig-utils.c32
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c213
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.h6
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.h26
-rw-r--r--src/gtk+-2.x/ctkevent.c2
-rw-r--r--src/gtk+-2.x/ctkframelock.c15
-rw-r--r--src/gtk+-2.x/ctkgvo.c7
-rw-r--r--src/gtk+-2.x/ctkmultisample.c2
-rw-r--r--src/gtk+-2.x/ctkui.c4
-rw-r--r--src/gtk+-2.x/ctkui.h2
-rw-r--r--src/libXNVCtrl/NVCtrl.h8
-rw-r--r--src/libXNVCtrl/libXNVCtrl.abin17180 -> 17180 bytes
-rw-r--r--src/libXNVCtrl/nv_control.h2
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.c4
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.h11
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c17
-rw-r--r--src/nvidia-settings.c39
-rw-r--r--src/parse.c37
-rw-r--r--src/parse.h1
23 files changed, 532 insertions, 145 deletions
diff --git a/src/XF86Config-parser/Scan.c b/src/XF86Config-parser/Scan.c
index ab48af8..22b6557 100644
--- a/src/XF86Config-parser/Scan.c
+++ b/src/XF86Config-parser/Scan.c
@@ -584,7 +584,6 @@ static int pathIsSafe(const char *path)
* %E config file environment ($XF86CONFIG) as an absolute path
* %F config file environment ($XF86CONFIG) as a relative path
* %G config file environment ($XF86CONFIG) as a safe path
- * %D $HOME
* %P projroot
* %M major version number
* %% %
@@ -640,7 +639,7 @@ static char *DoSubstitution(const char *template,
{
char *result;
int i, l;
- static const char *env = NULL, *home = NULL;
+ static const char *env = NULL;
static char *hostname = NULL;
static char majorvers[3] = "";
@@ -731,14 +730,6 @@ static char *DoSubstitution(const char *template,
} else
BAIL_OUT;
break;
- case 'D':
- if (!home)
- home = getenv("HOME");
- if (home && pathIsAbsolute(home))
- APPEND_STR(home);
- else
- BAIL_OUT;
- break;
case 'P':
if (projroot && pathIsAbsolute(projroot))
APPEND_STR(projroot);
@@ -798,7 +789,6 @@ static const char __root_configpath[] =
"%F," /* $XF86CONFIG (as relative path) */
"/etc/X11/%F," /* /etc/X11/$XF86CONFIG */
"%P/etc/X11/%F," /* /usr/X11R6/etc/X11/$XF86CONFIG */
-"%D/%X," /* $HOME/XF86Config */
"/etc/X11/%X-%M," /* /etc/X11/XF86Config-4 */
"/etc/X11/%X," /* /etc/X11/XF86Config */
"/etc/%X," /* /etc/XF86Config */
diff --git a/src/config-file.c b/src/config-file.c
index 481f868..df4d5b3 100644
--- a/src/config-file.c
+++ b/src/config-file.c
@@ -707,6 +707,9 @@ static int parse_config_property(const char *file, const char *line, ConfigPrope
char *no_spaces, *s;
char *locale;
ConfigPropertiesTableEntry *t;
+ char *timer, *token;
+ TimerConfigProperty *c = NULL;
+ int interval;
int ret = NV_FALSE;
unsigned int flag;
@@ -726,9 +729,53 @@ static int parse_config_property(const char *file, const char *line, ConfigPrope
nv_warning_msg("Error parsing configuration file '%s': could "
"not set the specified locale '%s'.",
file, locale);
+ }
+ } else if (nv_strcasecmp(no_spaces, "Timer")) {
+ timer = ++s;
+
+ token = strtok(timer, ",");
+ if (!token)
+ goto done;
+
+ c = malloc(sizeof(TimerConfigProperty));
+ if (!c) {
+ nv_warning_msg("Error parsing configuration file '%s': could "
+ "not allocate memory for timer '%s'.",
+ file, timer);
ret = NV_TRUE;
goto done;
}
+
+ c->description = replace_characters(token, '_', ' ');
+ if (!c->description) {
+ nv_warning_msg("Error parsing configuration file '%s': could "
+ "not allocate memory for timer '%s'.",
+ file, timer);
+ ret = NV_TRUE;
+ goto done;
+ }
+
+ token = strtok(NULL, ",");
+ if (!token)
+ goto done;
+
+ if (nv_strcasecmp(token, "Yes")) {
+ c->user_enabled = 1;
+ } else if (nv_strcasecmp(token, "No")) {
+ c->user_enabled = 0;
+ } else {
+ goto done;
+ }
+
+ token = strtok(NULL, ",");
+ if (!token)
+ goto done;
+
+ parse_read_integer(token, &interval);
+ c->interval = interval;
+
+ c->next = conf->timers;
+ conf->timers = c;
} else {
for (t = configPropertyTable, flag = 0; t->name; t++) {
if (nv_strcasecmp(no_spaces, t->name)) {
@@ -754,6 +801,12 @@ static int parse_config_property(const char *file, const char *line, ConfigPrope
done:
+ if ((ret != NV_TRUE) && c) {
+ if (c->description)
+ free(c->description);
+ free(c);
+ }
+
if (no_spaces) free(no_spaces);
return ret;
@@ -770,6 +823,8 @@ static int parse_config_property(const char *file, const char *line, ConfigPrope
static void write_config_properties(FILE *stream, ConfigProperties *conf, char *locale)
{
ConfigPropertiesTableEntry *t;
+ TimerConfigProperty *c;
+ char *description;
fprintf(stream, "\n");
fprintf(stream, "# ConfigProperties:\n");
@@ -781,6 +836,16 @@ static void write_config_properties(FILE *stream, ConfigProperties *conf, char *
fprintf(stream, "%s = %s\n", t->name,
(t->flag & conf->booleans) ? "Yes" : "No");
}
+
+ for (c = conf->timers; (c != NULL); c = c->next) {
+ description = replace_characters(c->description, ' ', '_');
+ if (!description)
+ continue;
+ fprintf(stream, "Timer = %s,%s,%u\n",
+ description, c->user_enabled ? "Yes" : "No",
+ c->interval);
+ free(description);
+ }
} /* write_config_properties()*/
diff --git a/src/config-file.h b/src/config-file.h
index ae787ce..683b5b3 100644
--- a/src/config-file.h
+++ b/src/config-file.h
@@ -41,9 +41,17 @@
#define CONFIG_PROPERTIES_INCLUDE_DISPLAY_NAME_IN_CONFIG_FILE (1<<3)
#define CONFIG_PROPERTIES_SHOW_QUIT_DIALOG (1<<4)
+typedef struct _TimerConfigProperty {
+ char *description;
+ unsigned int user_enabled;
+ unsigned int interval;
+ struct _TimerConfigProperty *next;
+} TimerConfigProperty;
+
typedef struct {
unsigned int booleans;
char *locale;
+ TimerConfigProperty *timers;
} ConfigProperties;
diff --git a/src/gtk+-2.x/ctkconfig.c b/src/gtk+-2.x/ctkconfig.c
index 181b8b1..de7806e 100644
--- a/src/gtk+-2.x/ctkconfig.c
+++ b/src/gtk+-2.x/ctkconfig.c
@@ -36,6 +36,7 @@
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
static const char *__tooltip_help =
"When ToolTips are enabled, descriptions will be displayed next to options "
@@ -470,6 +471,12 @@ GtkTextBuffer *ctk_config_create_help(GtkTextTagTable *table)
#define MAX_TIME_INTERVAL (60 * 1000)
#define MIN_TIME_INTERVAL (100)
+static void enabled_renderer_func(GtkTreeViewColumn*, GtkCellRenderer*,
+ GtkTreeModel*, GtkTreeIter*, gpointer);
+
+static void description_renderer_func(GtkTreeViewColumn*, GtkCellRenderer*,
+ GtkTreeModel*, GtkTreeIter*, gpointer);
+
static void time_interval_renderer_func(GtkTreeViewColumn*, GtkCellRenderer*,
GtkTreeModel*, GtkTreeIter*, gpointer);
@@ -481,9 +488,8 @@ static void timer_enable_toggled(GtkCellRendererToggle*, gchar*, gpointer);
enum {
- USER_ENABLE_COLUMN = 0,
- TIME_INTERVAL_COLUMN,
- DESCRIPTION_COLUMN,
+
+ TIMER_CONFIG_COLUMN = 0,
FUNCTION_COLUMN,
DATA_COLUMN,
HANDLE_COLUMN,
@@ -509,9 +515,7 @@ static GtkWidget *create_timer_list(CtkConfig *ctk_config)
ctk_config->list_store =
gtk_list_store_new(NUM_COLUMNS,
- G_TYPE_BOOLEAN, /* USER_ENABLE_COLUMN */
- G_TYPE_UINT, /* TIME_INTERVAL_COLUMN */
- G_TYPE_STRING, /* DESCRIPTION_COLUMN */
+ G_TYPE_POINTER, /* TIMER_CONFIG_COLUMN */
G_TYPE_POINTER, /* FUNCTION_COLUMN */
G_TYPE_POINTER, /* DATA_COLUMN */
G_TYPE_UINT, /* HANDLE_COLUMN */
@@ -529,29 +533,41 @@ static GtkWidget *create_timer_list(CtkConfig *ctk_config)
g_signal_connect(renderer, "toggled",
G_CALLBACK(timer_enable_toggled), ctk_config);
column = gtk_tree_view_column_new_with_attributes("Enabled", renderer,
- "active", USER_ENABLE_COLUMN,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
gtk_tree_view_column_set_resizable(column, FALSE);
+ gtk_tree_view_column_set_cell_data_func(column,
+ renderer,
+ enabled_renderer_func,
+ GINT_TO_POINTER
+ (TIMER_CONFIG_COLUMN),
+ NULL);
+
/* Description */
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Description",
renderer,
- "text",
- DESCRIPTION_COLUMN,
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
gtk_tree_view_column_set_resizable(column, TRUE);
+
+ gtk_tree_view_column_set_cell_data_func(column,
+ renderer,
+ description_renderer_func,
+ GINT_TO_POINTER
+ (TIMER_CONFIG_COLUMN),
+ NULL);
/* Time interval */
renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes
- ("Time Interval", renderer, "editable", TRUE, NULL);
+ column = gtk_tree_view_column_new_with_attributes("Time Interval",
+ renderer,
+ NULL);
g_signal_connect(renderer, "edited",
G_CALLBACK(time_interval_edited), ctk_config);
@@ -560,7 +576,7 @@ static GtkWidget *create_timer_list(CtkConfig *ctk_config)
renderer,
time_interval_renderer_func,
GINT_TO_POINTER
- (TIME_INTERVAL_COLUMN),
+ (TIMER_CONFIG_COLUMN),
NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
@@ -589,6 +605,40 @@ static GtkWidget *create_timer_list(CtkConfig *ctk_config)
} /* create_timer_list() */
+static void enabled_renderer_func(GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gint column;
+ TimerConfigProperty *timer_config;
+ gboolean value;
+
+ column = GPOINTER_TO_INT(data);
+ gtk_tree_model_get(model, iter, column, &timer_config, -1);
+
+ value = timer_config->user_enabled;
+ g_object_set(GTK_CELL_RENDERER(cell), "active", value, NULL);
+}
+
+static void description_renderer_func(GtkTreeViewColumn *tree_column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gint column;
+ TimerConfigProperty *timer_config;
+ gchar *value;
+
+ column = GPOINTER_TO_INT(data);
+ gtk_tree_model_get(model, iter, column, &timer_config, -1);
+
+ value = timer_config->description;
+ g_object_set(GTK_CELL_RENDERER(cell), "text", value, NULL);
+}
+
static void time_interval_renderer_func(GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *model,
@@ -596,14 +646,17 @@ static void time_interval_renderer_func(GtkTreeViewColumn *tree_column,
gpointer data)
{
gint column = GPOINTER_TO_INT(data);
+ TimerConfigProperty *timer_config;
guint value;
gchar str[32];
- gtk_tree_model_get(model, iter, column, &value, -1);
+ gtk_tree_model_get(model, iter, column, &timer_config, -1);
+ value = timer_config->interval;
snprintf(str, 32, "%d ms", value);
g_object_set(GTK_CELL_RENDERER(cell), "text", str, NULL);
+ g_object_set(GTK_CELL_RENDERER(cell), "editable", TRUE, NULL);
}
@@ -621,7 +674,7 @@ static void time_interval_edited(GtkCellRendererText *cell,
GSourceFunc function;
gpointer data;
guint interval;
- gboolean user_enabled;
+ TimerConfigProperty *timer_config;
gboolean owner_enabled;
interval = strtol(new_text, (char **)NULL, 10);
@@ -636,20 +689,19 @@ static void time_interval_edited(GtkCellRendererText *cell,
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_path_free(path);
- gtk_list_store_set(ctk_config->list_store, &iter,
- TIME_INTERVAL_COLUMN, interval, -1);
-
gtk_tree_model_get(model, &iter,
- USER_ENABLE_COLUMN, &user_enabled,
+ TIMER_CONFIG_COLUMN, &timer_config,
OWNER_ENABLE_COLUMN, &owner_enabled,
HANDLE_COLUMN, &handle,
FUNCTION_COLUMN, &function,
DATA_COLUMN, &data,
-1);
+
+ timer_config->interval = interval;
/* Restart the timer if it is already running */
- if (user_enabled && owner_enabled) {
+ if (timer_config->user_enabled && owner_enabled) {
g_source_remove(handle);
@@ -671,8 +723,7 @@ static void timer_enable_toggled(GtkCellRendererToggle *cell,
guint handle;
GSourceFunc function;
gpointer data;
- guint interval;
- gboolean user_enabled;
+ TimerConfigProperty *timer_config;
gboolean owner_enabled;
path = gtk_tree_path_new_from_string(path_string);
@@ -680,30 +731,26 @@ static void timer_enable_toggled(GtkCellRendererToggle *cell,
gtk_tree_path_free(path);
gtk_tree_model_get(model, &iter,
- USER_ENABLE_COLUMN, &user_enabled,
+ TIMER_CONFIG_COLUMN, &timer_config,
OWNER_ENABLE_COLUMN, &owner_enabled,
HANDLE_COLUMN, &handle,
FUNCTION_COLUMN, &function,
DATA_COLUMN, &data,
- TIME_INTERVAL_COLUMN, &interval,
-1);
- user_enabled ^= 1;
+ timer_config->user_enabled ^= 1;
/* Start/stop the timer only when the owner widget has enabled it */
if (owner_enabled) {
- if (user_enabled) {
- handle = g_timeout_add(interval, function, data);
+ if (timer_config->user_enabled) {
+ handle = g_timeout_add(timer_config->interval, function, data);
gtk_list_store_set(ctk_config->list_store, &iter,
HANDLE_COLUMN, handle, -1);
} else {
g_source_remove(handle);
}
}
-
- gtk_list_store_set(ctk_config->list_store, &iter,
- USER_ENABLE_COLUMN, user_enabled, -1);
}
void ctk_config_add_timer(CtkConfig *ctk_config,
@@ -713,16 +760,38 @@ void ctk_config_add_timer(CtkConfig *ctk_config,
gpointer data)
{
GtkTreeIter iter;
- gchar *s = g_strdup(descr);
+ ConfigProperties *conf = ctk_config->conf;
+ TimerConfigProperty *timer_config;
+
+ if (strchr(descr, '_') || strchr(descr, ','))
+ return;
+
+ timer_config = conf->timers;
+ while (timer_config != NULL) {
+ if (strcmp(timer_config->description, descr) == 0)
+ break;
+ timer_config = timer_config->next;
+ }
+
+ if (timer_config == NULL) {
+ timer_config = g_malloc(sizeof(TimerConfigProperty));
+ if (timer_config == NULL)
+ return;
+
+ timer_config->description = g_strdup(descr);
+ timer_config->user_enabled = TRUE;
+ timer_config->interval = interval;
+
+ timer_config->next = conf->timers;
+ conf->timers = timer_config;
+ }
/* Timer defaults to user enabled/owner disabled */
gtk_list_store_append(ctk_config->list_store, &iter);
gtk_list_store_set(ctk_config->list_store, &iter,
- USER_ENABLE_COLUMN, TRUE,
+ TIMER_CONFIG_COLUMN, timer_config,
OWNER_ENABLE_COLUMN, FALSE,
- TIME_INTERVAL_COLUMN, interval,
- DESCRIPTION_COLUMN, s,
FUNCTION_COLUMN, function,
DATA_COLUMN, data, -1);
@@ -744,29 +813,26 @@ void ctk_config_remove_timer(CtkConfig *ctk_config, GSourceFunc function)
GSourceFunc func;
gboolean valid;
guint handle;
- gboolean user_enabled;
+ TimerConfigProperty *timer_config;
gboolean owner_enabled;
- gchar *descr;
-
model = GTK_TREE_MODEL(ctk_config->list_store);
valid = gtk_tree_model_get_iter_first(model, &iter);
while (valid) {
gtk_tree_model_get(model, &iter,
+ TIMER_CONFIG_COLUMN, &timer_config,
FUNCTION_COLUMN, &func,
- USER_ENABLE_COLUMN, &user_enabled,
OWNER_ENABLE_COLUMN, &owner_enabled,
- DESCRIPTION_COLUMN, &descr,
HANDLE_COLUMN, &handle, -1);
if (func == function) {
/* Remove the timer if it was running */
- if (user_enabled && owner_enabled) {
+ if (timer_config->user_enabled && owner_enabled) {
g_source_remove(handle);
}
- g_free(descr);
+
gtk_list_store_remove(ctk_config->list_store, &iter);
break;
}
@@ -790,8 +856,7 @@ void ctk_config_start_timer(CtkConfig *ctk_config, GSourceFunc function, gpointe
GSourceFunc func;
gboolean valid;
guint handle;
- guint interval;
- gboolean user_enabled;
+ TimerConfigProperty *timer_config;
gboolean owner_enabled;
gpointer model_data;
@@ -800,20 +865,19 @@ void ctk_config_start_timer(CtkConfig *ctk_config, GSourceFunc function, gpointe
valid = gtk_tree_model_get_iter_first(model, &iter);
while (valid) {
gtk_tree_model_get(model, &iter,
- USER_ENABLE_COLUMN, &user_enabled,
+ TIMER_CONFIG_COLUMN, &timer_config,
OWNER_ENABLE_COLUMN, &owner_enabled,
HANDLE_COLUMN, &handle,
FUNCTION_COLUMN, &func,
DATA_COLUMN, &model_data,
- TIME_INTERVAL_COLUMN, &interval,
-1);
if ((func == function) && (model_data == data)) {
/* Start the timer if is enabled by the user and
it is not already running. */
- if (user_enabled && !owner_enabled) {
- handle = g_timeout_add(interval, function, data);
+ if (timer_config->user_enabled && !owner_enabled) {
+ handle = g_timeout_add(timer_config->interval, function, data);
gtk_list_store_set(ctk_config->list_store, &iter,
HANDLE_COLUMN, handle, -1);
}
@@ -832,8 +896,7 @@ void ctk_config_stop_timer(CtkConfig *ctk_config, GSourceFunc function, gpointer
GSourceFunc func;
gboolean valid;
guint handle;
- guint interval;
- gboolean user_enabled;
+ TimerConfigProperty *timer_config;
gboolean owner_enabled;
gpointer model_data;
@@ -842,18 +905,17 @@ void ctk_config_stop_timer(CtkConfig *ctk_config, GSourceFunc function, gpointer
valid = gtk_tree_model_get_iter_first(model, &iter);
while (valid) {
gtk_tree_model_get(model, &iter,
- USER_ENABLE_COLUMN, &user_enabled,
+ TIMER_CONFIG_COLUMN, &timer_config,
OWNER_ENABLE_COLUMN, &owner_enabled,
HANDLE_COLUMN, &handle,
FUNCTION_COLUMN, &func,
DATA_COLUMN, &model_data,
- TIME_INTERVAL_COLUMN, &interval,
-1);
if ((func == function) && (model_data == data)) {
/* Remove the timer if was running. */
- if (user_enabled && owner_enabled) {
+ if (timer_config->user_enabled && owner_enabled) {
g_source_remove(handle);
}
gtk_list_store_set(ctk_config->list_store, &iter,
diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.c b/src/gtk+-2.x/ctkdisplayconfig-utils.c
index 610ab51..4bf924d 100644
--- a/src/gtk+-2.x/ctkdisplayconfig-utils.c
+++ b/src/gtk+-2.x/ctkdisplayconfig-utils.c
@@ -741,8 +741,8 @@ Bool display_add_modelines_from_server(nvDisplayPtr display, gchar **err_str)
char *modeline_strs = NULL;
char *str;
int len;
- ReturnStatus ret;
-
+ ReturnStatus ret, ret1;
+ int major = 0, minor = 0;
/* Free any old mode lines */
display_remove_modelines(display);
@@ -783,7 +783,27 @@ Bool display_add_modelines_from_server(nvDisplayPtr display, gchar **err_str)
nv_error_msg(*err_str);
goto fail;
}
-
+
+ /*
+ * check the version of the NV-CONTROL protocol -- versions <=
+ * 1.13 had a bug in how they reported double scan modelines
+ * (vsyncstart, vsyncend, and vtotal were doubled); determine
+ * if this X server has this bug, so that we can use
+ * broken_doublescan_modelines to correctly compute the
+ * refresh rate.
+ */
+ modeline->broken_doublescan_modelines = 1;
+
+ ret = NvCtrlGetAttribute(display->gpu->handle,
+ NV_CTRL_ATTR_NV_MAJOR_VERSION, &major);
+ ret1 = NvCtrlGetAttribute(display->gpu->handle,
+ NV_CTRL_ATTR_NV_MINOR_VERSION, &minor);
+
+ if ((ret == NvCtrlSuccess) && (ret1 == NvCtrlSuccess) &&
+ ((major > 1) || ((major == 1) && (minor > 13)))) {
+ modeline->broken_doublescan_modelines = 0;
+ }
+
/* Add the modeline at the end of the display's modeline list */
display->modelines = (nvModeLinePtr)xconfigAddListItem
((GenericListPtr)display->modelines, (GenericListPtr)modeline);
@@ -2072,6 +2092,12 @@ static Bool layout_add_gpu_from_server(nvLayoutPtr layout, unsigned int gpu_id,
goto fail;
}
+ ret = NvCtrlGetAttribute(gpu->handle, NV_CTRL_DEPTH_30_ALLOWED,
+ &(gpu->allow_depth_30));
+
+ if (ret != NvCtrlSuccess) {
+ gpu->allow_depth_30 = FALSE;
+ }
/* Add the display devices to the GPU */
if (!gpu_add_displays_from_server(gpu, err_str)) {
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 9d841a7..cdea7d9 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -134,7 +134,7 @@ typedef struct SwitchModeCallbackInfoRec {
#define VALIDATE_APPLY 0
#define VALIDATE_SAVE 1
-
+#define SCREEN_DEPTH_COUNT 4
/*** G L O B A L S ***********************************************************/
@@ -302,6 +302,28 @@ static void check_screen_pos_changed(CtkDisplayConfig *ctk_object)
+/** layout_supports_depth_30() ***************************************
+ *
+ * Returns TRUE if all the GPUs in the layout that have screens
+ * support depth 30.
+ *
+ **/
+
+static gboolean layout_supports_depth_30(nvLayoutPtr layout)
+{
+ nvGpuPtr gpu;
+
+ for (gpu = layout->gpus; gpu; gpu = gpu->next) {
+ if ((gpu->num_screens) && (!gpu->allow_depth_30)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+
+} /* layout_supports_depth_30() */
+
+
+
/** consolidate_xinerama() *******************************************
*
* Ensures that all X screens have the same depth if Xinerama is
@@ -324,7 +346,16 @@ static void consolidate_xinerama(CtkDisplayConfig *ctk_object,
}
if (!screen) return;
- /* If Xinerama is enabled, all screens must have the same bpp. */
+ /**
+ * Make sure all screens support depth 30, and if not,
+ * we should set depth 24.
+ **/
+
+ if ((screen->depth == 30) && (layout_supports_depth_30(layout) == FALSE)) {
+ screen->depth = 24;
+ }
+
+ /* If Xinerama is enabled, all screens must have the same depth. */
for (gpu = screen->gpu->layout->gpus; gpu; gpu = gpu->next) {
for (other = gpu->screens; other; other = other->next) {
if (other == screen) continue;
@@ -846,20 +877,22 @@ static void screen_primary_display_toggled(GtkWidget *widget,
gpointer user_data)
{
CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
- gint enabled;
+ gint enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
nvScreenPtr screen = display->screen;
- enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
if (enabled) {
screen->primaryDisplay = display;
}
- //Make the apply button sensitive to user input
+ /* Make the apply button sensitive to user input */
gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+
} /* screen_primary_display_toggled() */
+
+
/** ctk_display_config_new() *****************************************
*
* Display Configuration widget creation.
@@ -875,7 +908,6 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
GtkWidget *banner;
GtkWidget *frame;
GtkWidget *notebook;
- GtkWidget *tab_label;
GtkWidget *hbox;
GtkWidget *hbox2;
GtkWidget *vbox;
@@ -1378,19 +1410,13 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
/* Panel for the notebook sections */
- vbox = gtk_vbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(ctk_object), vbox, FALSE, FALSE, 5);
+ notebook = gtk_notebook_new();
+ ctk_object->notebook = notebook;
+ gtk_box_pack_start(GTK_BOX(ctk_object), notebook, FALSE, FALSE, 0);
- { /* Display section */
+ { /* Display page */
GtkWidget *longest_hbox;
-
- /* Create the display page */
- tab_label = gtk_label_new("Display");
- notebook = gtk_notebook_new();
- hbox = gtk_hbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), notebook, TRUE, TRUE, 5);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
/* Generate the major vbox for the display section */
vbox = gtk_vbox_new(FALSE, 5);
@@ -1484,8 +1510,8 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
hbox = gtk_hbox_new(FALSE, 5);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
ctk_object->chk_primary_display =
- gtk_check_button_new_with_label("Make this Primary Display "
- "for X Screen");
+ gtk_check_button_new_with_label("Make this the primary display "
+ "for the X screen");
ctk_config_set_tooltip(ctk_config, ctk_object->chk_primary_display,
__dpy_primary_help);
g_signal_connect(G_OBJECT(ctk_object->chk_primary_display), "toggled",
@@ -1496,14 +1522,17 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
gtk_widget_set_size_request(label, req.width, -1);
gtk_box_pack_start(GTK_BOX(hbox), ctk_object->chk_primary_display,
TRUE, TRUE, 0);
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, tab_label);
+
+ /* Up the object ref count to make sure that the page and its widgets
+ * do not get freed if/when the page is removed from the notebook.
+ */
+ g_object_ref(ctk_object->display_page);
+ gtk_widget_show_all(ctk_object->display_page);
+
} /* Display sub-section */
- { /* X screen */
-
- /* Create the X screen page */
- tab_label = gtk_label_new("X Screen");
+ { /* X screen page */
/* Generate the major vbox for the display section */
vbox = gtk_vbox_new(FALSE, 5);
@@ -1564,7 +1593,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
TRUE, TRUE, 0);
ctk_object->box_screen_metamode = hbox;
- gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, tab_label);
+ /* Up the object ref count to make sure that the page and its widgets
+ * do not get freed if/when the page is removed from the notebook.
+ */
+ g_object_ref(ctk_object->screen_page);
+ gtk_widget_show_all(ctk_object->screen_page);
+
} /* X screen sub-section */
@@ -2744,12 +2778,20 @@ static void setup_display_page(CtkDisplayConfig *ctk_object)
{
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+ gint page_num;
+ GtkWidget *tab_label;
- /* If no display is selected or there is no screen, hide the frame */
+ page_num = gtk_notebook_page_num(GTK_NOTEBOOK(ctk_object->notebook),
+ ctk_object->display_page);
+
+ /* If no display is selected, remove the display page */
if (!display) {
gtk_widget_set_sensitive(ctk_object->display_page, False);
- gtk_widget_hide(ctk_object->display_page);
+ if (page_num >= 0) {
+ gtk_notebook_remove_page(GTK_NOTEBOOK(ctk_object->notebook),
+ page_num);
+ }
return;
}
@@ -2781,10 +2823,17 @@ static void setup_display_page(CtkDisplayConfig *ctk_object)
/* Setup panning */
setup_display_panning(ctk_object);
+
/* Setup first display */
setup_primary_display(ctk_object);
- gtk_widget_show(ctk_object->display_page);
+
+ /* Make sure the page has been added to the notebook */
+ if (page_num < 0) {
+ tab_label = gtk_label_new("Display");
+ gtk_notebook_prepend_page(GTK_NOTEBOOK(ctk_object->notebook),
+ ctk_object->display_page, tab_label);
+ }
} /* setup_display_page() */
@@ -2801,6 +2850,9 @@ static void setup_screen_depth_dropdown(CtkDisplayConfig *ctk_object)
{
GtkWidget *menu;
GtkWidget *menu_item;
+ int cur_idx;
+ int screen_depth_table_len = 0;
+ gboolean add_depth_30_option;
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
@@ -2808,18 +2860,44 @@ static void setup_screen_depth_dropdown(CtkDisplayConfig *ctk_object)
gtk_widget_hide(ctk_object->box_screen_depth);
return;
}
+ if (ctk_object->screen_depth_table) {
+ free(ctk_object->screen_depth_table);
+ }
+ ctk_object->screen_depth_table =
+ (char *) malloc(sizeof(char) * SCREEN_DEPTH_COUNT);
+ menu = gtk_menu_new();
+
+ /* If Xinerama is enabled, only allow depth 30 if all
+ * gpu/screens have support for depth 30.
+ */
- menu = gtk_menu_new();
- menu_item = gtk_menu_item_new_with_label("Millions of Colors (32 bpp)");
+ if (ctk_object->layout->xinerama_enabled) {
+ add_depth_30_option = layout_supports_depth_30(display->gpu->layout);
+ } else {
+ add_depth_30_option = display->gpu->allow_depth_30;
+ }
+
+ if (add_depth_30_option) {
+ menu_item = gtk_menu_item_new_with_label
+ ("1.1 Billion Colors (Depth 30) - Experimental");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_widget_show(menu_item);
+ ctk_object->screen_depth_table[screen_depth_table_len++] = 30;
+ }
+ menu_item = gtk_menu_item_new_with_label("16.7 Million Colors (Depth 24)");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_widget_show(menu_item);
- menu_item = gtk_menu_item_new_with_label("Thousands of Colors (16 bpp)");
+ ctk_object->screen_depth_table[screen_depth_table_len++] = 24;
+
+ menu_item = gtk_menu_item_new_with_label("65,536 Colors (Depth 16)");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_widget_show(menu_item);
- menu_item = gtk_menu_item_new_with_label("256 Colors (8 bpp)");
+ ctk_object->screen_depth_table[screen_depth_table_len++] = 16;
+ menu_item = gtk_menu_item_new_with_label("256 Colors (Depth 8)");
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
gtk_widget_show(menu_item);
+ ctk_object->screen_depth_table[screen_depth_table_len++] = 8;
g_signal_handlers_block_by_func(G_OBJECT(ctk_object->mnu_screen_depth),
G_CALLBACK(screen_depth_changed),
@@ -2827,16 +2905,12 @@ static void setup_screen_depth_dropdown(CtkDisplayConfig *ctk_object)
gtk_option_menu_set_menu
(GTK_OPTION_MENU(ctk_object->mnu_screen_depth), menu);
-
- if (display->screen->depth == 24) {
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_depth), 0);
- } else if (display->screen->depth == 16) {
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_depth), 1);
- } else {
- gtk_option_menu_set_history
- (GTK_OPTION_MENU(ctk_object->mnu_screen_depth), 2);
+
+ for (cur_idx = 0; cur_idx < SCREEN_DEPTH_COUNT; cur_idx++) {
+ if (display->screen->depth == ctk_object->screen_depth_table[cur_idx]) {
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_object->mnu_screen_depth), cur_idx);
+ }
}
g_signal_handlers_unblock_by_func(G_OBJECT(ctk_object->mnu_screen_depth),
@@ -3134,12 +3208,21 @@ static void setup_screen_page(CtkDisplayConfig *ctk_object)
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
gchar *tmp;
+ gint page_num;
+ GtkWidget *tab_label;
+
+
+ page_num = gtk_notebook_page_num(GTK_NOTEBOOK(ctk_object->notebook),
+ ctk_object->screen_page);
- /* If there is no display or no screen selected, hide the frame */
+ /* If there is no display or no screen selected, remove the screen page */
if (!display || !display->screen) {
gtk_widget_set_sensitive(ctk_object->screen_page, False);
- gtk_widget_hide(ctk_object->screen_page);
+ if (page_num >= 0) {
+ gtk_notebook_remove_page(GTK_NOTEBOOK(ctk_object->notebook),
+ page_num);
+ }
return;
}
@@ -3166,8 +3249,13 @@ static void setup_screen_page(CtkDisplayConfig *ctk_object)
setup_screen_metamode(ctk_object);
- gtk_widget_show(ctk_object->screen_page);
-
+ /* Make sure the page has been added to the notebook */
+ if (page_num < 0) {
+ tab_label = gtk_label_new("X Screen");
+ gtk_notebook_append_page(GTK_NOTEBOOK(ctk_object->notebook),
+ ctk_object->screen_page, tab_label);
+ }
+
} /* setup_screen_page() */
@@ -4847,6 +4935,8 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data)
} /* display_resolution_changed() */
+
+
/** display_modelname_changed() *****************************
*
* Called when user selectes a new display from display modelname dropdown.
@@ -4868,8 +4958,11 @@ static void display_modelname_changed(GtkWidget *widget, gpointer user_data)
/* Reconfigure GUI to display information about the selected display. */
setup_display_page(ctk_object);
setup_screen_page(ctk_object);
+
} /* display_modelname_changed() */
+
+
/** display_position_type_changed() **********************************
*
* Called when user selects a new display position method (relative/
@@ -5071,17 +5164,31 @@ static void screen_depth_changed(GtkWidget *widget, gpointer user_data)
{
CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
gint idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
- int depth = 8;
+ int depth;
nvScreenPtr screen = ctk_display_layout_get_selected_screen
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
-
+
if (!screen) return;
- /* Set the new default depth of the screen */
- if (idx == 0) {
- depth = 24;
- } else if (idx == 1) {
- depth = 16;
+ depth = ctk_object->screen_depth_table[idx];
+
+ if (depth == 30) {
+ GtkWidget *dlg;
+ GtkWidget *parent = ctk_get_parent_window(GTK_WIDGET(ctk_object));
+ dlg = gtk_message_dialog_new (GTK_WINDOW(parent),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK,
+ "Note that Depth 30 requires recent X "
+ "server updates for correct operation. "
+ "Also, some X applications may not work "
+ "correctly with depth 30.\n\n"
+ "Please see the Chapter \"Configuring "
+ "Depth 30 Displays\" "
+ "in the README for details.");
+ gtk_dialog_run(GTK_DIALOG(dlg));
+ gtk_widget_destroy (dlg);
+
}
ctk_display_layout_set_screen_depth
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), screen, depth);
@@ -5418,7 +5525,7 @@ static void xinerama_state_toggled(GtkWidget *widget, gpointer user_data)
/* Can't dynamically enable Xinerama */
ctk_object->apply_possible = FALSE;
- /* Make sure all screens have the same bpp when Xinerama is enabled */
+ /* Make sure all screens have the same depth when Xinerama is enabled */
consolidate_xinerama(ctk_object, NULL);
setup_screen_page(ctk_object);
diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h
index 2917c1d..0921447 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.h
+++ b/src/gtk+-2.x/ctkdisplayconfig.h
@@ -68,6 +68,8 @@ typedef struct _CtkDisplayConfig
GtkWidget *chk_xinerama_enabled;
GtkWidget *chk_primary_display;
+ GtkWidget *notebook; /* Tabbed notebook for display and X screen pages */
+
/* Display - Info */
GtkWidget *display_page;
@@ -124,8 +126,8 @@ typedef struct _CtkDisplayConfig
GtkWidget *btn_screen_metamode;
GtkWidget *btn_screen_metamode_add;
GtkWidget *btn_screen_metamode_delete;
-
-
+
+ char *screen_depth_table;
/* Dialogs */
GtkWidget *dlg_display_config;
GtkWidget *rad_display_config_disabled;
diff --git a/src/gtk+-2.x/ctkdisplaylayout.h b/src/gtk+-2.x/ctkdisplaylayout.h
index c20913e..5b51c7a 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.h
+++ b/src/gtk+-2.x/ctkdisplaylayout.h
@@ -124,10 +124,18 @@ G_BEGIN_DECLS
(!strcmp(( m )->data.identifier, "nvidia-auto-select"))
-/* Calculates the vertical refresh rate of the modeline in Hz */
-#define GET_MODELINE_REFRESH_RATE(m) \
-(((double)((m)->data.clock) * 1000) / \
- ((double)((m)->data.htotal) * (double)((m)->data.vtotal)))
+/* Calculates the vertical refresh rate of the modeline in Hz; if the
+ * divide by two for double scan modes (if the double scan modeline
+ * isn't broken; i.e., already has a correct vtotal), and multiply by
+ * two for interlaced modes (so that we report the field rate, rather
+ * than the frame rate)
+ */
+#define GET_MODELINE_REFRESH_RATE(m) \
+((((double)((m)->data.clock) * 1000) / \
+ ((double)((m)->data.htotal) * (double)((m)->data.vtotal))) * \
+ ((((m)->data.flags & V_DBLSCAN) && \
+ !(m)->broken_doublescan_modelines) ? 0.5 : 1.0) * \
+ (((m)->data.flags & V_INTERLACE) ? 2.0 : 1.0))
/* Calculates the horizontal refresh rate (sync) of the modeline in kHz */
@@ -148,7 +156,14 @@ typedef struct nvModeLineRec {
/* Extra information */
unsigned int source;
char *xconfig_name;
-
+
+ /* older versions of the NV-CONTROL protocol reported doublescan
+ * modeline values with doubled vsyncstart, vsyncend, and vtotal;
+ * track whether this X server has this bug, so we know how to
+ * compute the refresh rate from the modeline
+ */
+ int broken_doublescan_modelines;
+
} nvModeLine, *nvModeLinePtr;
@@ -279,6 +294,7 @@ typedef struct nvGpuRec {
int max_width;
int max_height;
int max_displays;
+ Bool allow_depth_30;
char *name; /* Name of the GPU */
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index 877217d..edcffc4 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -255,7 +255,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_NOTEBOOK_INTERNAL_LCD
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DEPTH_30_ALLOWED
#warning "There are attributes that do not emit signals!"
#endif
diff --git a/src/gtk+-2.x/ctkframelock.c b/src/gtk+-2.x/ctkframelock.c
index 7aa1a76..4b376c7 100644
--- a/src/gtk+-2.x/ctkframelock.c
+++ b/src/gtk+-2.x/ctkframelock.c
@@ -4159,6 +4159,7 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
ReturnStatus ret;
unsigned int num_framelocks;
+ gchar *string;
GtkWidget *frame;
GtkWidget *padding;
@@ -4536,18 +4537,28 @@ GtkWidget* ctk_framelock_new(NvCtrlAttributeHandle *handle,
/* register a timer callback to update the status of the page */
+ string = g_strdup_printf("Frame Lock Connection Status (Screen %u)",
+ NvCtrlGetTargetId(handle));
+
ctk_config_add_timer(ctk_config, DEFAULT_UPDATE_STATUS_TIME_INTERVAL,
- "Frame Lock Connection Status",
+ string,
(GSourceFunc) update_framelock_status,
(gpointer) ctk_framelock);
+
+ g_free(string);
/* register a timer callback to check the rj45 ports */
+ string = g_strdup_printf("Frame Lock RJ45 Check (Screen %u)",
+ NvCtrlGetTargetId(handle));
+
ctk_config_add_timer(ctk_config, DEFAULT_CHECK_FOR_ETHERNET_TIME_INTERVAL,
- "Frame Lock RJ45 Check",
+ string,
(GSourceFunc) check_for_ethernet,
(gpointer) ctk_framelock);
+ g_free(string);
+
return GTK_WIDGET(object);
} /* ctk_framelock_new() */
diff --git a/src/gtk+-2.x/ctkgvo.c b/src/gtk+-2.x/ctkgvo.c
index be71c69..3e903ed 100644
--- a/src/gtk+-2.x/ctkgvo.c
+++ b/src/gtk+-2.x/ctkgvo.c
@@ -806,12 +806,17 @@ GtkWidget* ctk_gvo_new(NvCtrlAttributeHandle *handle,
g_timeout_add(UPDATE_GVO_BANNER_TIME_INTERVAL, update_gvo_banner,
&ctk_gvo->banner);
+ string = g_strdup_printf("Graphics To Video Probe (Screen %u)",
+ NvCtrlGetTargetId(handle));
+
ctk_config_add_timer(ctk_gvo->ctk_config,
DEFAULT_GVO_PROBE_TIME_INTERVAL,
- "Graphics To Video Probe",
+ string,
(GSourceFunc) ctk_gvo_probe,
(gpointer) ctk_gvo);
+ g_free(string);
+
register_for_gvo_events(ctk_gvo);
diff --git a/src/gtk+-2.x/ctkmultisample.c b/src/gtk+-2.x/ctkmultisample.c
index d2cb367..1e2b9d0 100644
--- a/src/gtk+-2.x/ctkmultisample.c
+++ b/src/gtk+-2.x/ctkmultisample.c
@@ -1325,7 +1325,7 @@ GtkTextBuffer *ctk_multisample_create_help(GtkTextTagTable *table,
"the slider.");
ctk_help_para(b, &i, "Enhance Application Settings will make "
"applications that are requesting some type of "
- "antialiasing to use the mode selected by the "
+ "antialiasing mode use the mode selected by the "
"slider.");
} else {
ctk_help_para(b, &i, __aa_override_app_help);
diff --git a/src/gtk+-2.x/ctkui.c b/src/gtk+-2.x/ctkui.c
index 42fd756..25ecdb8 100644
--- a/src/gtk+-2.x/ctkui.c
+++ b/src/gtk+-2.x/ctkui.c
@@ -32,9 +32,9 @@
* that nvidia-settings.c doesn't need to include gtk+
*/
-void ctk_init(int *argc, char **argv[])
+int ctk_init_check(int *argc, char **argv[])
{
- gtk_init(argc, argv);
+ return gtk_init_check(argc, argv);
}
char *ctk_get_display(void)
diff --git a/src/gtk+-2.x/ctkui.h b/src/gtk+-2.x/ctkui.h
index 2993565..4aa8a85 100644
--- a/src/gtk+-2.x/ctkui.h
+++ b/src/gtk+-2.x/ctkui.h
@@ -29,7 +29,7 @@
#include "parse.h"
#include "config-file.h"
-void ctk_init(int *argc, char **argv[]);
+int ctk_init_check(int *argc, char **argv[]);
char *ctk_get_display(void);
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index f146e4a..865d5c0 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -3157,8 +3157,14 @@
#define NV_CTRL_NOTEBOOK_INTERNAL_LCD 278 /* R-- */
+/*
+ * NV_CTRL_DEPTH_30_ALLOWED - returns whether the NVIDIA X driver supports
+ * depth 30 on the specified X screen or GPU.
+ */
+
+#define NV_CTRL_DEPTH_30_ALLOWED 279 /* R--G */
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_NOTEBOOK_INTERNAL_LCD
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DEPTH_30_ALLOWED
/**************************************************************************/
diff --git a/src/libXNVCtrl/libXNVCtrl.a b/src/libXNVCtrl/libXNVCtrl.a
index c18ed09..092eacb 100644
--- a/src/libXNVCtrl/libXNVCtrl.a
+++ b/src/libXNVCtrl/libXNVCtrl.a
Binary files differ
diff --git a/src/libXNVCtrl/nv_control.h b/src/libXNVCtrl/nv_control.h
index e655961..62133c6 100644
--- a/src/libXNVCtrl/nv_control.h
+++ b/src/libXNVCtrl/nv_control.h
@@ -6,7 +6,7 @@
#define NV_CONTROL_NAME "NV-CONTROL"
#define NV_CONTROL_MAJOR 1
-#define NV_CONTROL_MINOR 13
+#define NV_CONTROL_MINOR 14
#define X_nvCtrlQueryExtension 0
#define X_nvCtrlIsNv 1
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
index 5894520..ac873a1 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
@@ -550,7 +550,9 @@ NvCtrlGetDisplayAttribute(NvCtrlAttributeHandle *handle,
return NvCtrlSuccess;
}
- if ((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) {
+ if (((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) ||
+ ((attr >= NV_CTRL_ATTR_NV_BASE) &&
+ (attr <= NV_CTRL_ATTR_NV_LAST_ATTRIBUTE))) {
if (!h->nv) return NvCtrlMissingExtension;
return NvCtrlNvControlGetAttribute(h, display_mask, attr, val);
}
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
index 0cd3edd..ebd206a 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
@@ -92,9 +92,18 @@ typedef void NvCtrlAttributeHandle;
#define NV_CTRL_ATTR_EXT_LAST_ATTRIBUTE \
(NV_CTRL_ATTR_EXT_XV_BLITTER_PRESENT)
-#define NV_CTRL_ATTR_XV_BASE \
+#define NV_CTRL_ATTR_NV_BASE \
(NV_CTRL_ATTR_EXT_LAST_ATTRIBUTE + 1)
+#define NV_CTRL_ATTR_NV_MAJOR_VERSION (NV_CTRL_ATTR_NV_BASE + 0)
+#define NV_CTRL_ATTR_NV_MINOR_VERSION (NV_CTRL_ATTR_NV_BASE + 1)
+
+#define NV_CTRL_ATTR_NV_LAST_ATTRIBUTE \
+ (NV_CTRL_ATTR_NV_MINOR_VERSION)
+
+#define NV_CTRL_ATTR_XV_BASE \
+ (NV_CTRL_ATTR_NV_LAST_ATTRIBUTE + 1)
+
#define NV_CTRL_ATTR_XV_OVERLAY_SATURATION (NV_CTRL_ATTR_XV_BASE + 0)
#define NV_CTRL_ATTR_XV_OVERLAY_CONTRAST (NV_CTRL_ATTR_XV_BASE + 1)
#define NV_CTRL_ATTR_XV_OVERLAY_BRIGHTNESS (NV_CTRL_ATTR_XV_BASE + 2)
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
index 46c2c80..20a165e 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c
@@ -116,7 +116,22 @@ ReturnStatus NvCtrlNvControlGetAttribute (NvCtrlAttributePrivateHandle *h,
return NvCtrlAttributeNotAvailable;
}
}
-
+
+ if ((attr >= NV_CTRL_ATTR_NV_BASE) &&
+ (attr <= NV_CTRL_ATTR_NV_LAST_ATTRIBUTE)) {
+
+ if (!h->nv) return NvCtrlMissingExtension;
+
+ switch (attr) {
+ case NV_CTRL_ATTR_NV_MAJOR_VERSION:
+ *val = h->nv->major_version;
+ return NvCtrlSuccess;
+ case NV_CTRL_ATTR_NV_MINOR_VERSION:
+ *val = h->nv->minor_version;
+ return NvCtrlSuccess;
+ }
+ }
+
return NvCtrlNoAttribute;
} /* NvCtrlNvControlGetAttribute() */
diff --git a/src/nvidia-settings.c b/src/nvidia-settings.c
index d82e355..75e48f0 100644
--- a/src/nvidia-settings.c
+++ b/src/nvidia-settings.c
@@ -44,21 +44,37 @@ int main(int argc, char **argv)
NvCtrlAttributeHandle **vcsc_handles = NULL;
Options *op;
int ret, i, num_screen_handles, num_gpu_handles, num_vcsc_handles;
-
+ char *dpy = NULL;
+ int gui = 0;
+
/*
* initialize the ui
*
* XXX it would be nice if we didn't do this up front, since we
* may not even use the gui, but we want the toolkit to have a
- * chance to parse the commandline before we do... we should
- * investigate gtk_init_check().
+ * chance to parse the commandline before we do...
+ *
+ * gui flag used to decide if ctk should be used or not, as
+ * the user might just use control the display from a remote console
+ * but for some reason cannot initialize the gtk gui. - TY 2005-05-27
*/
-
- ctk_init(&argc, &argv);
+
+ if (ctk_init_check(&argc, &argv)) {
+ dpy = ctk_get_display();
+ gui = 1;
+ }
/* parse the commandline */
- op = parse_command_line(argc, argv, ctk_get_display());
+ op = parse_command_line(argc, argv, dpy);
+
+ /* quit here if we don't have a ctrl_display - TY 2005-05-27 */
+
+ if (op->ctrl_display == NULL) {
+ nv_error_msg("The control display is undefined; please run "
+ "`%s --help` for usage information.\n", argv[0]);
+ return 1;
+ }
/* process any query or assignment commandline options */
@@ -109,6 +125,17 @@ int main(int argc, char **argv)
return ret ? 0 : 1;
}
+ /*
+ * past this point, we need to be able to create a gui; fail if
+ * the gui isn't available; TY 2005-05-27
+ */
+
+ if (gui == 0) {
+ nv_error_msg("Unable to create nvidia-settings GUI; please run "
+ "`%s --help` for usage information.\n", argv[0]);
+ return 1;
+ }
+
/* allocate the CtrlHandles for this X screen */
h = nv_alloc_ctrl_handles(op->ctrl_display);
diff --git a/src/parse.c b/src/parse.c
index 9442955..803ee89 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -94,6 +94,7 @@ AttributeTableEntry attributeTable[] = {
{ "SwitchToDisplays", NV_CTRL_SWITCH_TO_DISPLAYS, D|N|W },
{ "AssociatedDisplays", NV_CTRL_ASSOCIATED_DISPLAY_DEVICES, N|D },
{ "ProbeDisplays", NV_CTRL_PROBE_DISPLAYS, A },
+ { "Depth30Allowed", NV_CTRL_DEPTH_30_ALLOWED, N },
{ "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, 0 },
{ "GammaCorrectedAALines", NV_CTRL_OPENGL_AA_LINE_GAMMA, 0 },
{ "ShowSLIHUD", NV_CTRL_SHOW_SLI_HUD, 0 },
@@ -244,7 +245,7 @@ AttributeTableEntry attributeTable[] = {
* about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_NOTEBOOK_INTERNAL_LCD
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DEPTH_30_ALLOWED
#warning "Have you forgotten to add a new integer attribute to attributeTable?"
#endif
@@ -1177,6 +1178,40 @@ char *remove_spaces(const char *o)
+/*
+ * allocate an output string and copy the input string to this
+ * output string, replacing any occurances of the character
+ * 'c' with the character 'r'.
+ */
+
+char *replace_characters(const char *o, const char c, const char r)
+{
+ int len;
+ char *m, *out;
+
+ if (!o)
+ return NULL;
+
+ len = strlen(o);
+
+ out = malloc(len + 1);
+ m = out;
+
+ while (*o != '\0') {
+ *m++ = (*o == c) ? r : *o;
+ o++;
+ }
+ *m = '\0';
+
+ len = (m - out + 1);
+ out = realloc(out, len);
+
+ return out;
+
+} /* replace_characters() */
+
+
+
/**************************************************************************/
diff --git a/src/parse.h b/src/parse.h
index ddf45b6..d6dddc1 100644
--- a/src/parse.h
+++ b/src/parse.h
@@ -244,6 +244,7 @@ int nv_strcasecmp(const char *, const char *);
char *remove_spaces(const char *o);
+char *replace_characters(const char *o, const char c, const char r);
/*
* diaplay_mask/display_name conversions: the NV-CONTROL X extension