diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:29:01 -0800 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2008-02-12 21:29:01 -0800 |
commit | 9d2899dd01e78209d5a6f0428bd52c22a9245b48 (patch) | |
tree | b3e7b68731fc01e723c2c102391e19e36fc09680 | |
parent | f984a7a8a1e090275f54c8c5ba33d30950a0c1f6 (diff) |
169.07169.07
-rw-r--r-- | src/XF86Config-parser/Scan.c | 12 | ||||
-rw-r--r-- | src/config-file.c | 65 | ||||
-rw-r--r-- | src/config-file.h | 8 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkconfig.c | 164 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig-utils.c | 32 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig.c | 213 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplayconfig.h | 6 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkdisplaylayout.h | 26 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkevent.c | 2 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkframelock.c | 15 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkgvo.c | 7 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkmultisample.c | 2 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkui.c | 4 | ||||
-rw-r--r-- | src/gtk+-2.x/ctkui.h | 2 | ||||
-rw-r--r-- | src/libXNVCtrl/NVCtrl.h | 8 | ||||
-rw-r--r-- | src/libXNVCtrl/libXNVCtrl.a | bin | 17180 -> 17180 bytes | |||
-rw-r--r-- | src/libXNVCtrl/nv_control.h | 2 | ||||
-rw-r--r-- | src/libXNVCtrlAttributes/NvCtrlAttributes.c | 4 | ||||
-rw-r--r-- | src/libXNVCtrlAttributes/NvCtrlAttributes.h | 11 | ||||
-rw-r--r-- | src/libXNVCtrlAttributes/NvCtrlAttributesNvControl.c | 17 | ||||
-rw-r--r-- | src/nvidia-settings.c | 39 | ||||
-rw-r--r-- | src/parse.c | 37 | ||||
-rw-r--r-- | src/parse.h | 1 |
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 Binary files differindex c18ed09..092eacb 100644 --- a/src/libXNVCtrl/libXNVCtrl.a +++ b/src/libXNVCtrl/libXNVCtrl.a 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 |