summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2020-10-07 08:53:59 -0700
committerAaron Plattner <aplattner@nvidia.com>2020-10-07 08:53:59 -0700
commit6d5ab9be83bbb279638a672dedda96cc39174759 (patch)
tree7eb446d92c83491f14947d5023dd5b77d02854da
parent3fac2b1bd245e109161a5efa9eac2a0fe811663b (diff)
455.28455.28
-rw-r--r--doc/version.mk2
-rw-r--r--samples/version.mk2
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c221
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.h4
-rw-r--r--src/gtk+-2.x/ctkgridlicense.c44
-rw-r--r--src/gtk+-2.x/ctkgridlicense.h1
-rw-r--r--src/gtk+-2.x/ctkslimm.c1110
-rw-r--r--src/gtk+-2.x/ctkslimm.h66
-rw-r--r--src/gtk+-2.x/ctkwindow.c14
-rw-r--r--src/libXNVCtrl/version.mk2
-rw-r--r--src/nvml.h20
-rw-r--r--src/version.h2
-rw-r--r--src/version.mk2
-rw-r--r--version.mk2
14 files changed, 837 insertions, 655 deletions
diff --git a/doc/version.mk b/doc/version.mk
index 618e84a..14d7f22 100644
--- a/doc/version.mk
+++ b/doc/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 455.23.04
+NVIDIA_VERSION = 455.28
diff --git a/samples/version.mk b/samples/version.mk
index 618e84a..14d7f22 100644
--- a/samples/version.mk
+++ b/samples/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 455.23.04
+NVIDIA_VERSION = 455.28
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 515264e..673e63a 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <sys/stat.h>
#include <assert.h>
+#include <math.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@@ -106,6 +107,7 @@ static void screen_metamode_delete_clicked(GtkWidget *widget, gpointer user_data
static void setup_prime_display_page(CtkDisplayConfig *ctk_object);
static void xinerama_state_toggled(GtkWidget *widget, gpointer user_data);
+static void mosaic_config_clicked(GtkWidget *widget, gpointer user_data);
static void apply_clicked(GtkWidget *widget, gpointer user_data);
static void save_clicked(GtkWidget *widget, gpointer user_data);
static void probe_clicked(GtkWidget *widget, gpointer user_data);
@@ -127,6 +129,7 @@ static XConfigPtr xconfig_generate(XConfigPtr xconfCur,
Bool *merged,
void *callback_data);
+static void update_layout(CtkDisplayConfig *ctk_object);
@@ -204,6 +207,10 @@ static const char * __layout_base_mosaic_surround_button_help =
static const char * __layout_base_mosaic_full_button_help =
"The Enable Base Mosaic checkbox enables Base Mosaic.";
+static const char * __layout_mosaic_config_button_help =
+"The Configure SLI Mosaic Displays button will open a dialog to assist in "
+"configuring multiple displays.";
+
static const char * __dpy_resolution_mnu_help =
"The Resolution drop-down allows you to select a desired resolution "
"for the currently selected display device. The 'scaled' qualifier indicates "
@@ -1913,6 +1920,12 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target,
xconfig_generate,
(void *)ctk_object);
+ ctk_object->dialog_mosaic =
+ create_mosaic_dialog(GTK_WIDGET(ctk_object),
+ ctk_object->ctrl_target,
+ ctk_object->ctk_config,
+ ctk_object->layout);
+
/* Apply button */
ctk_object->btn_apply = gtk_button_new_with_label("Apply");
@@ -1960,7 +1973,17 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target,
G_CALLBACK(save_clicked),
(gpointer) ctk_object);
+ /* Mosaic/Grid Config button */
+ ctk_object->btn_mosaic = gtk_button_new_with_label
+ ("Configure SLI Mosaic Displays");
+ ctk_config_set_tooltip(ctk_config, ctk_object->btn_mosaic,
+ __layout_mosaic_config_button_help);
+ g_signal_connect(G_OBJECT(ctk_object->btn_mosaic), "clicked",
+ G_CALLBACK(mosaic_config_clicked),
+ (gpointer) ctk_object);
+
{ /* Layout section */
+ GtkWidget *vbox2;
frame = gtk_frame_new("Layout"); /* main panel */
gtk_box_pack_start(GTK_BOX(ctk_object), frame, FALSE, FALSE, 0);
@@ -1973,13 +1996,22 @@ GtkWidget* ctk_display_config_new(CtrlTarget *ctrl_target,
TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(vbox), eventbox, TRUE, TRUE, 0);
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(vbox), hbox);
+ vbox2 = gtk_vbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(hbox), vbox2);
+
/* Mosaic checkbox */
- gtk_box_pack_start(GTK_BOX(vbox), ctk_object->chk_mosaic_enabled,
+ gtk_box_pack_start(GTK_BOX(vbox2), ctk_object->chk_mosaic_enabled,
FALSE, FALSE, 0);
/* Xinerama checkbox */
- gtk_box_pack_start(GTK_BOX(vbox), ctk_object->chk_xinerama_enabled,
+ gtk_box_pack_start(GTK_BOX(vbox2), ctk_object->chk_xinerama_enabled,
FALSE, FALSE, 0);
+
+ /* Mosaic configuration dialog button */
+ gtk_box_pack_end(GTK_BOX(hbox), ctk_object->btn_mosaic,
+ FALSE, FALSE, 0);
}
@@ -2524,6 +2556,8 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
case MOSAIC_TYPE_SLI_MOSAIC:
ctk_help_heading(b, &i, "Enable SLI Mosaic");
ctk_help_para(b, &i, "%s", __layout_sli_mosaic_button_help);
+ ctk_help_heading(b, &i, "Configure SLI Mosaic");
+ ctk_help_para(b, &i, "%s", __layout_mosaic_config_button_help);
break;
case MOSAIC_TYPE_BASE_MOSAIC:
ctk_help_heading(b, &i, "Enable Base Mosaic");
@@ -2667,6 +2701,12 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
ctk_help_heading(b, &i, "Save to X Configuration File");
ctk_help_para(b, &i, "%s", __save_button_help);
+
+ ctk_help_para(b, &i, "");
+ ctk_help_heading(b, &i, "Dialogs");
+
+ ctk_mmdialog_insert_help(b, &i);
+
ctk_help_finish(b);
return b;
@@ -2696,6 +2736,7 @@ static void setup_mosaic_config(CtkDisplayConfig *ctk_object)
if (!ctk_object->advanced_mode ||
(!display_gpu_support_mosaic && !screen_gpu_support_mosaic)) {
gtk_widget_hide(ctk_object->chk_mosaic_enabled);
+ gtk_widget_hide(ctk_object->btn_mosaic);
return;
}
@@ -2707,6 +2748,14 @@ static void setup_mosaic_config(CtkDisplayConfig *ctk_object)
gpu = screen->display_owner_gpu;
}
+ /* Only show the Mosaic Config tool with SLI Mosaic and dialog exists */
+ if (gpu->mosaic_type == MOSAIC_TYPE_SLI_MOSAIC &&
+ ctk_object->dialog_mosaic) {
+ gtk_widget_show(ctk_object->btn_mosaic);
+ } else {
+ gtk_widget_hide(ctk_object->btn_mosaic);
+ }
+
switch (gpu->mosaic_type) {
case MOSAIC_TYPE_SLI_MOSAIC:
tooltip = __layout_sli_mosaic_button_help;
@@ -6156,6 +6205,49 @@ static Bool display_build_modepool(nvDisplayPtr display, Bool *updated)
+static nvModeLinePtr
+display_find_closest_matching_modeline(nvDisplayPtr display,
+ nvModeLinePtr input_modeline)
+{
+ const int target_width = input_modeline->data.hdisplay;
+ const int target_height = input_modeline->data.vdisplay;
+ const double target_rr = input_modeline->refresh_rate;
+ const double tolerance = 0.0001;
+
+ nvModeLinePtr modeline, best_modeline = NULL;
+ int modeline_idx;
+ int best_idx = -1;
+
+ modeline_idx = 0;
+ for (modeline = display->modelines; modeline; modeline = modeline->next) {
+ if (modeline->data.hdisplay == target_width &&
+ modeline->data.vdisplay == target_height) {
+ nvModeLinePtr tmp_modeline = modeline;
+ int tmp_idx = modeline_idx;
+
+ /*
+ * We already have a match. Let's figure out if the currently
+ * considered modeline is the closer to what we want.
+ */
+ if (best_modeline) {
+ if (fabs(best_modeline->refresh_rate - target_rr) < tolerance) {
+ tmp_modeline = best_modeline;
+ tmp_idx = best_idx;
+ }
+ /* Fallthrough. */
+ }
+ best_modeline = tmp_modeline;
+ best_idx = tmp_idx;
+ }
+ modeline_idx++;
+ }
+
+ return best_modeline;
+
+} /* display_find_closest_matching_modeline() */
+
+
+
static void do_enable_mosaic(CtkDisplayConfig *ctk_object)
{
nvLayoutPtr layout = ctk_object->layout;
@@ -6199,6 +6291,76 @@ static void do_enable_mosaic(CtkDisplayConfig *ctk_object)
}
}
}
+
+ /* Enable the Mosaic Config dialog if available */
+ gtk_widget_set_sensitive(ctk_object->btn_mosaic, True);
+}
+
+
+
+static void mosaic_config_clicked(GtkWidget *widget, gpointer user_data)
+{
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
+ nvLayoutPtr layout = ctk_object->layout;
+ nvGpuPtr gpu;
+ gboolean enabled = gtk_toggle_button_get_active(
+ GTK_TOGGLE_BUTTON(ctk_object->chk_mosaic_enabled));
+
+ if (!enabled) {
+ return;
+ }
+
+ // Launch Mosaic Dialog //
+ if (run_mosaic_dialog(ctk_object->dialog_mosaic,
+ ctk_get_parent_window(GTK_WIDGET(ctk_object)),
+ ctk_object->layout)) {
+
+ // apply mosaic options and update screen //
+ int idx = ctk_object->dialog_mosaic->refresh_idx;
+ int display_num = 0;
+ nvModeLinePtr ml = ctk_object->dialog_mosaic->refresh_table[idx];
+
+ for(gpu = layout->gpus; gpu; gpu = gpu->next_in_layout) {
+ nvDisplayPtr display;
+
+ for(display = gpu->displays;
+ display;
+ display = display->next_on_gpu) {
+ nvModeLinePtr modeline;
+
+ if (display->num_selected_modes == 0) {
+ generate_selected_modes(display);
+ }
+
+ modeline = display_find_closest_matching_modeline(display, ml);
+
+ if (modeline) {
+ int x_loc, y_loc, x_pos, y_pos;
+
+ x_loc = display_num % ctk_object->dialog_mosaic->x_displays;
+ y_loc = display_num / ctk_object->dialog_mosaic->x_displays;
+
+ x_pos = x_loc * ml->data.hdisplay -
+ x_loc * ctk_object->dialog_mosaic->h_overlap;
+ y_pos = y_loc * ml->data.vdisplay -
+ y_loc * ctk_object->dialog_mosaic->v_overlap;
+
+ display_num++;
+
+ display->cur_mode->pan.x = x_pos;
+ display->cur_mode->pan.y = y_pos;
+
+ ctk_display_layout_set_mode_modeline(
+ CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
+ display->cur_mode, modeline, NULL, NULL);
+
+ }
+ }
+ }
+
+ update_layout(ctk_object);
+
+ }
}
@@ -6246,6 +6408,9 @@ static void do_disable_mosaic(CtkDisplayConfig *ctk_object)
*/
mosaic_screen->num_gpus = 0;
link_screen_to_gpu(mosaic_screen, mosaic_screen->display_owner_gpu);
+
+ /* Disable the Mosaic Config dialog if available */
+ gtk_widget_set_sensitive(ctk_object->btn_mosaic, False);
}
@@ -9016,7 +9181,7 @@ static int add_screen_to_xconfig(CtkDisplayConfig *ctk_object,
xconfigAddNewOption(&conf_screen->options, "BaseMosaic", "on");
break;
default:
- nv_warning_msg("Uknonwn mosaic mode %d",
+ nv_warning_msg("Unknown mosaic mode %d",
screen->display_owner_gpu->mosaic_type);
xconfigAddNewOption(&conf_screen->options, "SLI",
screen->sli_mode ? screen->sli_mode : "Off");
@@ -9637,6 +9802,39 @@ static gboolean layout_change_is_applyable(const nvLayoutPtr old,
return False;
}
+
+
+/** update_layout() *************************************************
+ *
+ * Update layout and redraw.
+ *
+ **/
+
+static void update_layout(CtkDisplayConfig *ctk_object)
+{
+ ctk_display_layout_set_layout((CtkDisplayLayout *)(ctk_object->obj_layout),
+ ctk_object->layout);
+
+ /* Make sure X screens have some kind of position */
+ assign_screen_positions(ctk_object);
+
+ update_gui(ctk_object);
+
+ /* Get new position */
+ get_cur_screen_pos(ctk_object);
+
+ /* Update the apply button */
+ ctk_object->apply_possible = TRUE;
+ update_btn_apply(ctk_object, TRUE);
+
+ ctk_object->forced_reset_allowed = TRUE; /* OK to reset w/o user input */
+ ctk_object->notify_user_of_reset = TRUE; /* Notify user of new changes */
+ ctk_object->reset_required = FALSE; /* No reset required to apply */
+
+}
+
+
+
/** reset_layout() *************************************************
*
* Load current X server settings.
@@ -9693,6 +9891,8 @@ static void reset_layout(CtkDisplayConfig *ctk_object)
ctk_object->apply_possible = TRUE;
update_btn_apply(ctk_object, allow_apply);
+ update_mosaic_dialog_ui(ctk_object->dialog_mosaic, ctk_object->layout);
+
ctk_object->forced_reset_allowed = TRUE; /* OK to reset w/o user input */
ctk_object->notify_user_of_reset = TRUE; /* Notify user of new changes */
ctk_object->reset_required = FALSE; /* No reset required to apply */
@@ -9849,6 +10049,21 @@ static void display_config_attribute_changed(GtkWidget *object,
{
CtkDisplayConfig *ctk_object = (CtkDisplayConfig *) user_data;
+ if(ctk_object->dialog_mosaic && ctk_object->dialog_mosaic->is_active) {
+ 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,
+ "A change to the display configuration "
+ "has been detected. The information "
+ "shown here may no longer be valid. "
+ "Please close this dialog.");
+ gtk_dialog_run(GTK_DIALOG(dlg));
+ gtk_widget_destroy (dlg);
+ }
+
if (ctk_object->ignore_reset_events) return;
ctk_object->ignore_reset_events = TRUE;
diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h
index c80200b..802ac80 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.h
+++ b/src/gtk+-2.x/ctkdisplayconfig.h
@@ -25,6 +25,7 @@
#include "ctkconfig.h"
#include "ctkdisplaylayout.h"
#include "ctkdisplayconfig-utils.h"
+#include "ctkslimm.h"
@@ -231,6 +232,8 @@ typedef struct _CtkDisplayConfig
SaveXConfDlg *save_xconfig_dlg;
+ CtkMMDialog *dialog_mosaic;
+
/* Buttons */
GtkWidget *btn_apply;
gboolean apply_possible; /* True if all modifications are applicable */
@@ -242,6 +245,7 @@ typedef struct _CtkDisplayConfig
GdkPoint cur_screen_pos; /* Keep track of the selected X screen's position */
+ GtkWidget *btn_mosaic;
GtkWidget *btn_save;
GtkWidget *btn_probe;
diff --git a/src/gtk+-2.x/ctkgridlicense.c b/src/gtk+-2.x/ctkgridlicense.c
index 52cba46..47e2394 100644
--- a/src/gtk+-2.x/ctkgridlicense.c
+++ b/src/gtk+-2.x/ctkgridlicense.c
@@ -1660,12 +1660,14 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
gtk_container_set_border_width(GTK_CONTAINER(vbox3), 5);
ctk_manage_grid_license->isvComputeSupported = is_feature_supported(ctk_manage_grid_license, NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE);
- if (ctk_manage_grid_license->isvComputeSupported) {
+ ctk_manage_grid_license->isQuadroSupported = is_feature_supported(ctk_manage_grid_license, NV_GRID_LICENSE_FEATURE_TYPE_QDWS);
+ if (ctk_manage_grid_license->isvComputeSupported && ctk_manage_grid_license->isQuadroSupported) {
ctk_manage_grid_license->radio_btn_vcompute = gtk_radio_button_new_with_label(NULL, ctk_manage_grid_license->productNamevCompute);
slist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(ctk_manage_grid_license->radio_btn_vcompute));
+
gtk_box_pack_start(GTK_BOX(vbox3), ctk_manage_grid_license->radio_btn_vcompute, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(ctk_manage_grid_license->radio_btn_vcompute), "button_id",
- GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE));
+ GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE));
g_signal_connect(G_OBJECT(ctk_manage_grid_license->radio_btn_vcompute), "toggled",
G_CALLBACK(license_edition_toggled),
@@ -1674,24 +1676,44 @@ GtkWidget* ctk_manage_grid_license_new(CtrlTarget *target,
ctk_manage_grid_license->radio_btn_qdws = gtk_radio_button_new_with_label(slist, ctk_manage_grid_license->productNameQvDWS);
slist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(ctk_manage_grid_license->radio_btn_qdws));
+ gtk_box_pack_start(GTK_BOX(vbox3), ctk_manage_grid_license->radio_btn_qdws, FALSE, FALSE, 0);
+ g_object_set_data(G_OBJECT(ctk_manage_grid_license->radio_btn_qdws), "button_id",
+ GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_QDWS));
+
+ g_signal_connect(G_OBJECT(ctk_manage_grid_license->radio_btn_qdws), "toggled",
+ G_CALLBACK(license_edition_toggled),
+ (gpointer) ctk_manage_grid_license);
+
+ }
+ else if (ctk_manage_grid_license->isvComputeSupported) {
+ ctk_manage_grid_license->radio_btn_vcompute = gtk_radio_button_new_with_label(NULL, ctk_manage_grid_license->productNamevCompute);
+ slist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(ctk_manage_grid_license->radio_btn_vcompute));
+
+ gtk_box_pack_start(GTK_BOX(vbox3), ctk_manage_grid_license->radio_btn_vcompute, FALSE, FALSE, 0);
+ g_object_set_data(G_OBJECT(ctk_manage_grid_license->radio_btn_vcompute), "button_id",
+ GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_VCOMPUTE));
+
+ g_signal_connect(G_OBJECT(ctk_manage_grid_license->radio_btn_vcompute), "toggled",
+ G_CALLBACK(license_edition_toggled),
+ (gpointer) ctk_manage_grid_license);
}
- else {
+ else if (ctk_manage_grid_license->isQuadroSupported) {
ctk_manage_grid_license->radio_btn_qdws = gtk_radio_button_new_with_label(NULL, ctk_manage_grid_license->productNameQvDWS);
slist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(ctk_manage_grid_license->radio_btn_qdws));
- }
- gtk_box_pack_start(GTK_BOX(vbox3), ctk_manage_grid_license->radio_btn_qdws, FALSE, FALSE, 0);
- g_object_set_data(G_OBJECT(ctk_manage_grid_license->radio_btn_qdws), "button_id",
- GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_QDWS));
+ gtk_box_pack_start(GTK_BOX(vbox3), ctk_manage_grid_license->radio_btn_qdws, FALSE, FALSE, 0);
+ g_object_set_data(G_OBJECT(ctk_manage_grid_license->radio_btn_qdws), "button_id",
+ GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_QDWS));
- g_signal_connect(G_OBJECT(ctk_manage_grid_license->radio_btn_qdws), "toggled",
- G_CALLBACK(license_edition_toggled),
- (gpointer) ctk_manage_grid_license);
+ g_signal_connect(G_OBJECT(ctk_manage_grid_license->radio_btn_qdws), "toggled",
+ G_CALLBACK(license_edition_toggled),
+ (gpointer) ctk_manage_grid_license);
+ }
ctk_manage_grid_license->radio_btn_vapp = gtk_radio_button_new_with_label(slist, GRID_VIRTUAL_APPLICATIONS);
gtk_box_pack_start(GTK_BOX(vbox3), ctk_manage_grid_license->radio_btn_vapp, FALSE, FALSE, 0);
g_object_set_data(G_OBJECT(ctk_manage_grid_license->radio_btn_vapp), "button_id",
- GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_VAPP));
+ GINT_TO_POINTER(NV_GRID_LICENSE_FEATURE_TYPE_VAPP));
g_signal_connect(G_OBJECT(ctk_manage_grid_license->radio_btn_vapp), "toggled",
G_CALLBACK(license_edition_toggled),
diff --git a/src/gtk+-2.x/ctkgridlicense.h b/src/gtk+-2.x/ctkgridlicense.h
index 9848ea2..404fc35 100644
--- a/src/gtk+-2.x/ctkgridlicense.h
+++ b/src/gtk+-2.x/ctkgridlicense.h
@@ -78,6 +78,7 @@ struct _CtkManageGridLicense
int licenseStatus; // Current license status to be displayed on UI
gboolean isvComputeSupported; // Check if 'NVIDIA Virtual Compute Server' feature is supported
+ gboolean isQuadroSupported; // Check if 'Quadro Virtual Data Center Workstation' feature is supported
};
/*
diff --git a/src/gtk+-2.x/ctkslimm.c b/src/gtk+-2.x/ctkslimm.c
index 67488e8..8464258 100644
--- a/src/gtk+-2.x/ctkslimm.c
+++ b/src/gtk+-2.x/ctkslimm.c
@@ -38,20 +38,18 @@
/* Static function declarations */
-static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object);
-static void setup_display_resolution_dropdown(CtkSLIMM *ctk_object);
-static void setup_total_size_label(CtkSLIMM *ctk_object);
+static void setup_display_refresh_dropdown(CtkMMDialog *ctk_object);
+static void setup_display_resolution_dropdown(CtkMMDialog *ctk_object);
+static void setup_total_size_label(CtkMMDialog *ctk_object);
static void display_refresh_changed(GtkWidget *widget, gpointer user_data);
static void display_resolution_changed(GtkWidget *widget, gpointer user_data);
static void display_config_changed(GtkWidget *widget, gpointer user_data);
static void txt_overlap_activated(GtkWidget *widget, gpointer user_data);
-static void slimm_checkbox_toggled(GtkWidget *widget, gpointer user_data);
-static void save_xconfig_button_clicked(GtkWidget *widget, gpointer user_data);
-static void add_slimm_options(XConfigPtr xconf, gchar *metamode_str);
-static void remove_slimm_options(XConfigPtr xconf);
+static void validate_screen_size(CtkMMDialog *ctk_object);
static nvDisplayPtr find_active_display(nvLayoutPtr layout);
-static nvDisplayPtr intersect_modelines(nvLayoutPtr layout);
-static void remove_duplicate_modelines(nvDisplayPtr display);
+static nvDisplayPtr intersect_modelines_list(CtkMMDialog *ctk_mmdialog,
+ nvLayoutPtr layout);
+static void remove_duplicate_modelines_from_list(CtkMMDialog *ctk_mmdialog);
static Bool other_displays_have_modeline(nvLayoutPtr layout,
nvDisplayPtr display,
nvModeLinePtr modeline);
@@ -65,161 +63,7 @@ typedef struct DpyLocRec { // Display Location
-
-GType ctk_slimm_get_type()
-{
- static GType ctk_slimm_type = 0;
-
- if (!ctk_slimm_type) {
- static const GTypeInfo info_ctk_slimm = {
- sizeof (CtkSLIMMClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- NULL, /* class_init */
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (CtkSLIMM),
- 0, /* n_preallocs */
- NULL, /* instance_init */
- NULL /* value_table */
- };
-
- ctk_slimm_type =
- g_type_register_static(GTK_TYPE_VBOX,
- "CtkSLIMM", &info_ctk_slimm, 0);
- }
-
- return ctk_slimm_type;
-}
-
-static void remove_slimm_options(XConfigPtr xconf)
-{
- /* Remove SLI Mosaic Option */
- xconfigRemoveNamedOption(&xconf->layouts->adjacencies->screen->options,
- "SLI", NULL);
-
- /* Remove MetaMode Option */
- xconfigRemoveNamedOption(&xconf->layouts->adjacencies->screen->options,
- "MetaModes", NULL);
-}
-
-
-static void add_slimm_options(XConfigPtr xconf, gchar *metamode_str)
-{
- XConfigAdjacencyPtr adj;
- XConfigScreenPtr screen;
-
- /* Make sure there is only one screen specified in the main layout */
- adj = xconf->layouts->adjacencies;
- while (adj->next) {
- xconfigRemoveListItem((GenericListPtr *)(&adj),
- (GenericListPtr)adj->next);
- }
-
- /*
- * Now fix up the screen in the Device section (to prevent failure with
- * separate x screen config
- *
- */
- xconf->layouts->adjacencies->screen->device->screen = -1;
-
- /* Write out SLI Mosaic Option */
- xconfigAddNewOption(&(xconf->layouts->adjacencies->screen->options),
- "SLI", "Mosaic");
-
- /* Write out MetaMode Option */
- xconfigAddNewOption(&(xconf->layouts->adjacencies->screen->options),
- "MetaModes", metamode_str);
-
- /* Remove Virtual size specification */
- for (screen = xconf->layouts->adjacencies->screen; screen;
- screen = screen->next) {
- if ((screen->displays->virtualX) || (screen->displays->virtualY)) {
- screen->displays->virtualX = 0;
- screen->displays->virtualY = 0;
- }
- }
-}
-
-
-
-static XConfigPtr xconfig_generate(XConfigPtr xconfCur,
- Bool merge,
- Bool *merged,
- void *callback_data)
-{
- CtkSLIMM *ctk_object = (CtkSLIMM *)callback_data;
- CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(ctk_object->mnu_display_config);
-
- gint idx;
-
- gint xctr,yctr;
-
- gint x_displays,y_displays;
- gint h_overlap, v_overlap;
-
- gchar *metamode_str = NULL;
- gchar *tmpstr;
-
- gint checkbox_state =
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ctk_object->cbtn_slimm_enable));
-
-
- /* Make sure we're being asked to merge */
- if (!xconfCur || !merge) {
- *merged = FALSE;
- return NULL;
- }
-
-
- if (checkbox_state) {
- /* SLI MM needs to be enabled */
- idx = ctk_drop_down_menu_get_current_value(menu);
-
- /* Get grid configuration values from index */
-
- if (idx < ctk_object->num_grid_configs) {
- x_displays = ctk_object->grid_configs[idx].columns;
- y_displays = ctk_object->grid_configs[idx].rows;
- } else {
- x_displays = y_displays = 0;
- }
-
- h_overlap = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ctk_object->spbtn_hedge_overlap));
- v_overlap = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ctk_object->spbtn_vedge_overlap));
-
- for (yctr = 0; yctr < y_displays;yctr++) {
- for (xctr = 0; xctr < x_displays;xctr++) {
- tmpstr = g_strdup_printf("%s +%d+%d",
- ctk_object->cur_modeline->data.identifier,
- ctk_object->cur_modeline->data.hdisplay * xctr -
- h_overlap * xctr,
- ctk_object->cur_modeline->data.vdisplay * yctr -
- v_overlap * yctr);
- if (metamode_str) {
- metamode_str = g_strconcat(metamode_str, ", ", tmpstr, NULL);
- g_free(tmpstr);
- } else {
- metamode_str = tmpstr;
- }
- }
- }
-
- add_slimm_options(xconfCur, metamode_str);
- } else {
- /* SLI MM needs to be disabled */
-
- remove_slimm_options(xconfCur);
- }
-
- *merged = TRUE;
-
- return xconfCur;
-}
-
-
-
-static void set_overlap_controls_status(CtkSLIMM *ctk_object)
+static void set_overlap_controls_status(CtkMMDialog *ctk_object)
{
CtkDropDownMenu *menu;
gint config_idx, x_displays, y_displays;
@@ -243,7 +87,7 @@ static void set_overlap_controls_status(CtkSLIMM *ctk_object)
-static Bool compute_screen_size(CtkSLIMM *ctk_object, gint *width,
+static Bool compute_screen_size(CtkMMDialog *ctk_object, gint *width,
gint *height)
{
gint config_idx;
@@ -282,9 +126,8 @@ static Bool compute_screen_size(CtkSLIMM *ctk_object, gint *width,
-static void save_xconfig_button_clicked(GtkWidget *widget, gpointer user_data)
+static void validate_screen_size(CtkMMDialog *ctk_object)
{
- CtkSLIMM *ctk_object = CTK_SLIMM(user_data);
gint width, height;
Bool error = FALSE;
gchar *err_msg = NULL;
@@ -324,22 +167,13 @@ static void save_xconfig_button_clicked(GtkWidget *widget, gpointer user_data)
g_free(err_msg);
return;
}
-
-
- /* Run the save dialog */
- if (run_save_xconfig_dialog(ctk_object->save_xconfig_dlg)) {
-
- /* Config file written */
- ctk_object->ctk_config->pending_config &=
- ~CTK_CONFIG_PENDING_WRITE_MOSAIC_CONFIG;
- }
}
static void txt_overlap_activated(GtkWidget *widget, gpointer user_data)
{
- CtkSLIMM *ctk_object = CTK_SLIMM(user_data);
+ CtkMMDialog *ctk_object = (CtkMMDialog *)(user_data);
/* Update total size label */
setup_total_size_label(ctk_object);
@@ -349,7 +183,7 @@ static void txt_overlap_activated(GtkWidget *widget, gpointer user_data)
static void display_config_changed(GtkWidget *widget, gpointer user_data)
{
- CtkSLIMM *ctk_object = CTK_SLIMM(user_data);
+ CtkMMDialog *ctk_object = (CtkMMDialog *)(user_data);
/* Update total size label */
setup_total_size_label(ctk_object);
@@ -360,7 +194,7 @@ static void display_config_changed(GtkWidget *widget, gpointer user_data)
static void display_refresh_changed(GtkWidget *widget, gpointer user_data)
{
- CtkSLIMM *ctk_object = CTK_SLIMM(user_data);
+ CtkMMDialog *ctk_object = (CtkMMDialog *)(user_data);
CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(widget);
gint idx;
@@ -377,7 +211,7 @@ static void display_refresh_changed(GtkWidget *widget, gpointer user_data)
static void display_resolution_changed(GtkWidget *widget, gpointer user_data)
{
- CtkSLIMM *ctk_object = CTK_SLIMM(user_data);
+ CtkMMDialog *ctk_object = (CtkMMDialog *)(user_data);
CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(widget);
gint idx;
@@ -418,39 +252,6 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data)
-static void slimm_checkbox_toggled(GtkWidget *widget, gpointer user_data)
-{
- CtkSLIMM *ctk_object = CTK_SLIMM(user_data);
-
- gint enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-
- if (enabled) {
- if (ctk_object->mnu_refresh_disabled) {
- ctk_object->mnu_refresh_disabled = False;
- gtk_widget_set_sensitive(ctk_object->mnu_display_refresh, True);
- }
- gtk_widget_set_sensitive(ctk_object->mnu_display_resolution, True);
- gtk_widget_set_sensitive(ctk_object->mnu_display_config, True);
- gtk_widget_set_sensitive(ctk_object->box_total_size, True);
- set_overlap_controls_status(ctk_object);
- } else {
- if (ctk_widget_get_sensitive(ctk_object->mnu_display_refresh)) {
- ctk_object->mnu_refresh_disabled = True;
- gtk_widget_set_sensitive(ctk_object->mnu_display_refresh, False);
- }
- gtk_widget_set_sensitive(ctk_object->mnu_display_resolution, False);
- gtk_widget_set_sensitive(ctk_object->mnu_display_config, False);
- gtk_widget_set_sensitive(ctk_object->spbtn_hedge_overlap, False);
- gtk_widget_set_sensitive(ctk_object->spbtn_vedge_overlap, False);
- gtk_widget_set_sensitive(ctk_object->box_total_size, False);
- }
-
- ctk_object->ctk_config->pending_config |=
- CTK_CONFIG_PENDING_WRITE_MOSAIC_CONFIG;
-}
-
-
-
/** setup_total_size_label() *********************************
*
* Generates and sets the label showing total X Screen size of all displays
@@ -458,7 +259,7 @@ static void slimm_checkbox_toggled(GtkWidget *widget, gpointer user_data)
*
**/
-static void setup_total_size_label(CtkSLIMM *ctk_object)
+static void setup_total_size_label(CtkMMDialog *ctk_object)
{
gint width, height;
gchar *xscreen_size;
@@ -471,6 +272,8 @@ static void setup_total_size_label(CtkSLIMM *ctk_object)
xscreen_size = g_strdup_printf("%d x %d", width, height);
gtk_label_set_text(GTK_LABEL(ctk_object->lbl_total_size), xscreen_size);
g_free(xscreen_size);
+
+ validate_screen_size(ctk_object);
}
@@ -482,12 +285,15 @@ static void setup_total_size_label(CtkSLIMM *ctk_object)
*
**/
-static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object)
+static void setup_display_refresh_dropdown(CtkMMDialog *ctk_object)
{
CtkDropDownMenu *menu;
- nvModeLinePtr modeline;
+ nvModeLinePtr modeline, m;
+ nvModeLineItemPtr item, i;
float cur_rate; /* Refresh Rate */
int cur_idx = 0; /* Currently selected modeline */
+ int idx;
+ int match_cur_modeline;
gchar *name; /* Modeline's label for the dropdown menu */
@@ -521,20 +327,40 @@ static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object)
ctk_drop_down_menu_reset(menu);
+ /* Make sure cur_modeline can possibly match resolution table */
+ match_cur_modeline = 0;
+ for (idx = 0; idx < ctk_object->resolution_table_len; idx++) {
+ m = ctk_object->resolution_table[idx];
+ if (m->data.hdisplay == ctk_object->cur_modeline->data.hdisplay &&
+ m->data.vdisplay == ctk_object->cur_modeline->data.vdisplay) {
+ match_cur_modeline = 1;
+ break;
+ }
+ }
+
/* Generate the refresh rate dropdown from the modelines list */
- for (modeline = ctk_object->modelines; modeline; modeline = modeline->next) {
+ for (item = ctk_object->modelines; item; item = item->next) {
float modeline_rate;
- nvModeLinePtr m;
int count_ref; /* # modelines with similar refresh rates */
int num_ref; /* Modeline # in a group of similar refresh rates */
gchar *extra = NULL;
gchar *tmp;
- /* Ignore modelines of different resolution */
- if (modeline->data.hdisplay != ctk_object->cur_modeline->data.hdisplay ||
- modeline->data.vdisplay != ctk_object->cur_modeline->data.vdisplay) {
+ modeline = item->modeline;
+
+ /* Ignore modelines of different resolution than the selected */
+ m = NULL;
+ if (match_cur_modeline) {
+ m = ctk_object->cur_modeline;
+ } else {
+ m = ctk_object->resolution_table[
+ ctk_object->cur_resolution_table_idx];
+ }
+
+ if (m && (modeline->data.hdisplay != m->data.hdisplay ||
+ modeline->data.vdisplay != m->data.vdisplay)) {
continue;
}
@@ -546,7 +372,8 @@ static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object)
/* Get a unique number for this modeline */
count_ref = 0; /* # modelines with similar refresh rates */
num_ref = 0; /* Modeline # in a group of similar refresh rates */
- for (m = ctk_object->modelines; m; m = m->next) {
+ for (i = ctk_object->modelines; i; i = i->next) {
+ nvModeLinePtr m = i->modeline;
float m_rate = m->refresh_rate;
gchar *tmp = g_strdup_printf("%.0f Hz", m_rate);
@@ -629,7 +456,6 @@ static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object)
}
/* Setup the menu and select the current mode */
- ctk_object->cur_modeline = ctk_object->refresh_table[cur_idx];
ctk_drop_down_menu_set_current_value(menu, cur_idx);
gtk_widget_set_sensitive(ctk_object->mnu_display_refresh, True);
@@ -656,10 +482,11 @@ static void setup_display_refresh_dropdown(CtkSLIMM *ctk_object)
*
**/
-static void setup_display_resolution_dropdown(CtkSLIMM *ctk_object)
+static void setup_display_resolution_dropdown(CtkMMDialog *ctk_object)
{
CtkDropDownMenu *menu;
+ nvModeLineItemPtr item;
nvModeLinePtr modeline;
nvModeLinePtr cur_modeline = ctk_object->cur_modeline;
@@ -679,26 +506,34 @@ static void setup_display_resolution_dropdown(CtkSLIMM *ctk_object)
/* Start the menu generation */
menu = CTK_DROP_DOWN_MENU(ctk_object->mnu_display_resolution);
- modeline = ctk_object->modelines;
+
+ item = ctk_object->modelines;
cur_idx = 0;
g_signal_handlers_block_by_func
(G_OBJECT(ctk_object->mnu_display_resolution),
G_CALLBACK(display_resolution_changed), (gpointer) ctk_object);
- /* Generate the resolution menu */
- while (modeline) {
+ ctk_drop_down_menu_reset(menu);
+
+ /* Generate the resolution menu */
+ while (item) {
+ nvModeLineItemPtr i;
nvModeLinePtr m;
gchar *name;
+ modeline = item->modeline;
+
/* Find the first resolution that matches the current res W & H */
- m = ctk_object->modelines;
+ i = ctk_object->modelines;
+ m = i->modeline;
while (m != modeline) {
+ m = i->modeline;
if (modeline->data.hdisplay == m->data.hdisplay &&
modeline->data.vdisplay == m->data.vdisplay) {
break;
}
- m = m->next;
+ i = i->next;
}
/* Add resolution if it is the first of its kind */
@@ -721,12 +556,13 @@ static void setup_display_resolution_dropdown(CtkSLIMM *ctk_object)
ctk_object->resolution_table[ctk_object->resolution_table_len++] =
modeline;
}
- modeline = modeline->next;
+ item = item->next;
}
/* Setup the menu and select the current mode */
ctk_drop_down_menu_set_current_value(menu, cur_idx);
+ ctk_object->cur_resolution_table_idx = cur_idx;
/* If dropdown has only one item, disable menu selection */
if (ctk_object->resolution_table_len > 1) {
@@ -775,12 +611,14 @@ static Bool add_array_value(int array[][2], int max_len, int *cur_len, int val)
return FALSE;
}
-static Bool parse_slimm_layout(CtkSLIMM *ctk_slimm,
+
+
+static Bool parse_slimm_layout(CtkMMDialog *ctk_mmdialog,
nvLayoutPtr layout,
int *hoverlap,
int *voverlap)
{
- CtrlTarget *ctrl_target = ctk_slimm->ctrl_target;
+ CtrlTarget *ctrl_target = ctk_mmdialog->ctrl_target;
ReturnStatus ret;
char *metamode_str = NULL;
char *str;
@@ -789,7 +627,7 @@ static Bool parse_slimm_layout(CtkSLIMM *ctk_slimm,
char *mode_name = NULL;
gchar *err_msg = NULL;
- const int max_locs = ctk_slimm->num_displays;
+ const int max_locs = ctk_mmdialog->num_displays;
int row_loc[max_locs][2]; // As position, count
int col_loc[max_locs][2]; // As position, count
DpyLoc locs[max_locs]; // Location of displays
@@ -999,8 +837,8 @@ static Bool parse_slimm_layout(CtkSLIMM *ctk_slimm,
*hoverlap += (*cur_modeline)->data.hdisplay;
}
- ctk_slimm->parsed_rows = rows;
- ctk_slimm->parsed_cols = cols;
+ ctk_mmdialog->parsed_rows = rows;
+ ctk_mmdialog->parsed_cols = cols;
free(metamode_str);
return TRUE;
@@ -1023,47 +861,42 @@ static Bool parse_slimm_layout(CtkSLIMM *ctk_slimm,
-static void remove_duplicate_modelines(nvDisplayPtr display)
+static void remove_duplicate_modelines_from_list(CtkMMDialog *ctk_mmdialog)
{
- nvModeLinePtr m, nextm;
- m = display->modelines;
- if (!m) {
+ nvModeLineItemPtr iter = ctk_mmdialog->modelines;
+ nvModeLineItemPtr tmp;
+ if (!iter) {
return;
}
/* Remove nvidia-auto-select modeline first */
- if (IS_NVIDIA_DEFAULT_MODE(m)) {
- display->modelines = m->next;
- if (m == display->cur_mode->modeline) {
- display->cur_mode->modeline = m->next;
- }
- modeline_free(m);
- display->num_modelines--;
+ if (IS_NVIDIA_DEFAULT_MODE(iter->modeline)) {
+ ctk_mmdialog->modelines = iter->next;
+ free(iter);
+ ctk_mmdialog->num_modelines--;
}
-
+
/* Remove duplicate modelines in active display - assuming sorted order*/
- for (m = display->modelines; m;) {
- nextm = m->next;
- if (!nextm) break;
-
- if (modelines_match(m, nextm)) {
- /* nextm is a duplicate - remove it. */
- m->next = nextm->next;
- if (nextm == display->cur_mode->modeline) {
- display->cur_mode->modeline = m;
- }
- modeline_free(nextm);
- display->num_modelines--;
+ for (iter = ctk_mmdialog->modelines; iter;) {
+ if (!iter->next) break;
+
+ if (modelines_match(iter->modeline, iter->next->modeline)) {
+ /* next is a duplicate - remove it. */
+ tmp = iter->next;
+ iter->next = iter->next->next;
+ free(tmp);
+ ctk_mmdialog->num_modelines--;
}
else {
- m = nextm;
+ iter = iter->next;
}
}
}
-static Bool other_displays_have_modeline(nvLayoutPtr layout,
+
+static Bool other_displays_have_modeline(nvLayoutPtr layout,
nvDisplayPtr display,
nvModeLinePtr modeline)
{
@@ -1100,13 +933,61 @@ static nvDisplayPtr find_active_display(nvLayoutPtr layout)
}
-static nvDisplayPtr intersect_modelines(nvLayoutPtr layout)
+
+static void add_modeline_to_list(CtkMMDialog *ctk_mmdialog, nvModeLinePtr m)
+{
+ nvModeLineItemPtr item;
+
+ if (!m) return;
+
+ item = calloc(1,sizeof(nvModeLineItem));
+ item->modeline = m;
+
+ if (!ctk_mmdialog->modelines) {
+ ctk_mmdialog->modelines = item;
+ ctk_mmdialog->num_modelines = 1;
+ } else {
+ nvModeLineItemPtr iter = ctk_mmdialog->modelines;
+ while (iter->next) {
+ iter = iter->next;
+ }
+ iter->next = item;
+ ctk_mmdialog->num_modelines++;
+ }
+}
+
+
+
+static void delete_modelines_list(CtkMMDialog *ctk_mmdialog)
+{
+ nvModeLineItemPtr item, next;
+
+ if (ctk_mmdialog->modelines == NULL || ctk_mmdialog->num_modelines == 0) {
+ return;
+ }
+
+ item = ctk_mmdialog->modelines;
+
+ while (item) {
+ next = item->next;
+ free(item);
+ item = next;
+ }
+
+ ctk_mmdialog->num_modelines = 0;
+ ctk_mmdialog->modelines = NULL;
+}
+
+
+
+static nvDisplayPtr intersect_modelines_list(CtkMMDialog *ctk_mmdialog,
+ const nvLayoutPtr layout)
{
nvDisplayPtr display;
- nvModeLinePtr m, prev;
+ nvModeLinePtr m;
- /**
- *
+ /**
+ *
* Only need to go through one active display, and eliminate all modelines
* in this display that do not exist in other displays (being driven by
* this or any other GPU)
@@ -1115,36 +996,17 @@ static nvDisplayPtr intersect_modelines(nvLayoutPtr layout)
display = find_active_display(layout);
if (display == NULL) return NULL;
- prev = NULL;
+ delete_modelines_list(ctk_mmdialog);
+
m = display->modelines;
while (m) {
- if (!other_displays_have_modeline(layout, display, m)) {
- if (prev) {
- /* Remove past beginning */
- prev->next = m->next;
- } else {
- /* Remove first entry */
- display->modelines = m->next;
- }
-
- if (m == display->cur_mode->modeline) {
- display->cur_mode->modeline = 0;
- }
- modeline_free(m);
- display->num_modelines--;
-
- if (prev) {
- m = prev->next;
- } else {
- m = display->modelines;
- }
- } else {
- prev = m;
- m = m->next;
+ if (other_displays_have_modeline(layout, display, m)) {
+ add_modeline_to_list(ctk_mmdialog, m);
}
+ m = m->next;
}
- remove_duplicate_modelines(display);
+ remove_duplicate_modelines_from_list(ctk_mmdialog);
return display;
}
@@ -1202,51 +1064,51 @@ static int generate_configs_helper(const int num_displays,
-static void generate_configs(CtkSLIMM *ctk_slimm, gboolean only_max)
+static void generate_configs(CtkMMDialog *ctk_mmdialog, gboolean only_max)
{
- int n_configs = generate_configs_helper(ctk_slimm->num_displays, only_max,
+ int n_configs = generate_configs_helper(ctk_mmdialog->num_displays, only_max,
NULL);
- ctk_slimm->grid_configs = calloc(n_configs, sizeof(GridConfig));
- ctk_slimm->num_grid_configs = n_configs;
+ ctk_mmdialog->grid_configs = calloc(n_configs, sizeof(GridConfig));
+ ctk_mmdialog->num_grid_configs = n_configs;
- generate_configs_helper(ctk_slimm->num_displays, only_max,
- ctk_slimm->grid_configs);
+ generate_configs_helper(ctk_mmdialog->num_displays, only_max,
+ ctk_mmdialog->grid_configs);
}
-static void populate_dropdown(CtkSLIMM *ctk_slimm, gboolean only_max)
+static void populate_dropdown(CtkMMDialog *ctk_mmdialog, gboolean only_max)
{
int iter;
int rows, cols;
int cur_rows, cur_cols;
char *tmp;
- CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(ctk_slimm->mnu_display_config);
+ CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(ctk_mmdialog->mnu_display_config);
int grid_config_id = ctk_drop_down_menu_get_current_value(menu);
- if (ctk_slimm->grid_configs && grid_config_id >= 0) {
- cur_rows = ctk_slimm->grid_configs[grid_config_id].rows;
- cur_cols = ctk_slimm->grid_configs[grid_config_id].columns;
+ if (ctk_mmdialog->grid_configs && grid_config_id >= 0) {
+ cur_rows = ctk_mmdialog->grid_configs[grid_config_id].rows;
+ cur_cols = ctk_mmdialog->grid_configs[grid_config_id].columns;
} else {
- cur_rows = ctk_slimm->parsed_rows;
- cur_cols = ctk_slimm->parsed_cols;
+ cur_rows = ctk_mmdialog->parsed_rows;
+ cur_cols = ctk_mmdialog->parsed_cols;
}
- if (ctk_slimm->grid_configs) {
- free(ctk_slimm->grid_configs);
- ctk_slimm->num_grid_configs = 0;
+ if (ctk_mmdialog->grid_configs) {
+ free(ctk_mmdialog->grid_configs);
+ ctk_mmdialog->num_grid_configs = 0;
}
ctk_drop_down_menu_reset(menu);
- generate_configs(ctk_slimm, only_max);
+ generate_configs(ctk_mmdialog, only_max);
- for (iter = 0; iter < ctk_slimm->num_grid_configs; iter++) {
- rows = ctk_slimm->grid_configs[iter].rows;
- cols = ctk_slimm->grid_configs[iter].columns;
+ for (iter = 0; iter < ctk_mmdialog->num_grid_configs; iter++) {
+ rows = ctk_mmdialog->grid_configs[iter].rows;
+ cols = ctk_mmdialog->grid_configs[iter].columns;
tmp = g_strdup_printf("%d x %d grid", rows, cols);
@@ -1265,36 +1127,203 @@ static void populate_dropdown(CtkSLIMM *ctk_slimm, gboolean only_max)
static void restrict_display_config_changed(GtkWidget *widget,
gpointer user_data)
{
- CtkSLIMM *ctk_slimm = CTK_SLIMM(user_data);
+ CtkMMDialog *ctk_mmdialog = (CtkMMDialog *)(user_data);
- populate_dropdown(ctk_slimm,
+ populate_dropdown(ctk_mmdialog,
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
+
+ update_mosaic_dialog_ui(ctk_mmdialog, NULL);
+}
+
+
+
+static void print_error_string(gchar *err_str)
+{
+ if (!err_str) {
+ nv_error_msg("Unable to load SLI Mosaic Mode Settings dialog.");
+ } else {
+ nv_error_msg("Unable to load SLI Mosaic Mode Settings "
+ "dialog:\n\n%s", err_str);
+ }
+}
+
+
+
+static nvDisplayPtr setup_display(CtkMMDialog *ctk_mmdialog)
+{
+ nvDisplayPtr display;
+ nvLayoutPtr layout = ctk_mmdialog->layout;
+
+ display = intersect_modelines_list(ctk_mmdialog, layout);
+
+ if (display == NULL) {
+ print_error_string("Unable to find active display with "
+ "intersected modelines.");
+ free(ctk_mmdialog);
+ return NULL;
+
+ } else if ((ctk_mmdialog->modelines == NULL)) {
+ /* The modepool for the active display did not have any modes in
+ * its modepool matching any of the modes on the modepool of any
+ * other display in the layout, causing intersect_modelines to
+ * remove every mode from the list of available modes for SLI mosaic
+ * mode.
+ *
+ * This can happen if one display had its modepool trimmed and modified
+ * to support 3D vision, while other displays (either on X screens
+ * without stereo currently enabled, or on screenless GPUs) did not.
+ * Find if that is the case, and display an informative message if so.
+ */
+ nvGpuPtr gpu;
+ nvDisplayPtr d;
+ int stereo = get_display_stereo_mode(display);
+
+ for (gpu = layout->gpus; gpu; gpu = gpu->next_in_layout) {
+ for (d = gpu->displays; d; d = d->next_on_gpu) {
+ int other_stereo;
+
+ if (display == d) {
+ continue;
+ }
+
+ other_stereo = get_display_stereo_mode(d);
+
+ if ((STEREO_IS_3D_VISION(stereo) &&
+ !STEREO_IS_3D_VISION(other_stereo)) ||
+ (!STEREO_IS_3D_VISION(stereo) &&
+ STEREO_IS_3D_VISION(other_stereo))) {
+
+ print_error_string("Unable to find common modelines between\n"
+ "all connected displays due to 3D vision\n"
+ "being enabled on some displays and not\n"
+ "others. Please make sure that 3D vision\n"
+ "is enabled on all connected displays\n"
+ "before enabling SLI mosaic mode.");
+
+ free(ctk_mmdialog);
+ return NULL;
+ }
+ }
+ }
+
+ /* The intersected modepool was empty, but not because of a mismatch
+ * in 3D Vision settings.
+ */
+ print_error_string("Unable to find find common modelines between "
+ "all connected displays.");
+
+ free(ctk_mmdialog);
+ return NULL;
+ }
+
+ if (display) {
+
+ /* Extract modelines and cur_modeline */
+ if (display->cur_mode->modeline) {
+ ctk_mmdialog->cur_modeline = display->cur_mode->modeline;
+ } else if (ctk_mmdialog->num_modelines > 0) {
+ ctk_mmdialog->cur_modeline = ctk_mmdialog->modelines->modeline;
+ }
+ }
+
+ return display;
}
+void update_mosaic_dialog_ui(CtkMMDialog *ctk_mmdialog, nvLayoutPtr layout)
+{
+ GtkWidget *btn;
+
+ if (ctk_mmdialog == NULL) {
+ return;
+ }
+
+ btn = ctk_mmdialog->chk_all_displays;
+
+ if (layout) {
+ ctk_mmdialog->layout = layout;
+ }
+
+ parse_slimm_layout(ctk_mmdialog,
+ ctk_mmdialog->layout,
+ &ctk_mmdialog->h_overlap_parsed,
+ &ctk_mmdialog->v_overlap_parsed);
+
+ setup_display(ctk_mmdialog);
+
+ populate_dropdown(ctk_mmdialog,
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(btn)));
+
+ setup_display_resolution_dropdown(ctk_mmdialog);
+ setup_display_refresh_dropdown(ctk_mmdialog);
+
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(ctk_mmdialog->spbtn_hedge_overlap),
+ ctk_mmdialog->h_overlap_parsed);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(ctk_mmdialog->spbtn_vedge_overlap),
+ ctk_mmdialog->v_overlap_parsed);
+ setup_total_size_label(ctk_mmdialog);
+}
-GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
- CtkEvent *ctk_event,
- CtkConfig *ctk_config)
+
+
+static gchar *count_displays_and_parse_layout(CtkMMDialog *ctk_mmdialog)
{
- GObject *object;
- CtkSLIMM *ctk_slimm;
+ nvLayoutPtr layout = ctk_mmdialog->layout;
+ gchar *err_str = NULL;
+
+ if (layout) {
+
+ nvGpuPtr gpu;
+ int num_displays = 0;
+
+ for (gpu = layout->gpus; gpu; gpu = gpu->next_in_layout) {
+ num_displays += gpu->num_displays;
+ }
+
+ ctk_mmdialog->num_displays = num_displays;
+
+
+ /* Make sure we have enough displays for the minimum config */
+ if (num_displays < 2) {
+ err_str = g_strdup_printf("Not enough display devices to "
+ "configure SLI Mosaic Mode.\nYou must "
+ "have at least 2 Displays connected, "
+ "but only %d Display%s detected.",
+ num_displays,
+ (num_displays != 1) ? "s were" : " was");
+ } else {
+ parse_slimm_layout(ctk_mmdialog,
+ layout,
+ &ctk_mmdialog->h_overlap_parsed,
+ &ctk_mmdialog->v_overlap_parsed);
+ }
+ }
+
+ return err_str;
+}
+
+
+
+CtkMMDialog *create_mosaic_dialog(GtkWidget *parent,
+ CtrlTarget *ctrl_target,
+ CtkConfig *ctk_config,
+ const nvLayoutPtr layout)
+{
+ GtkWidget *dialog_obj;
+ CtkMMDialog *ctk_mmdialog;
+ GtkWidget *content;
GtkWidget *label;
GtkWidget *vbox;
GtkWidget *hbox;
- GtkWidget *banner;
GtkWidget *checkbutton;
GtkWidget *hseparator;
GtkWidget *table;
- GtkWidget *button;
GtkWidget *spinbutton;
- CtkSLIMM *ctk_object;
CtkDropDownMenu *menu;
gchar *err_str = NULL;
- gchar *str;
gchar *tmp;
gchar *sli_mode = NULL;
ReturnStatus ret;
@@ -1302,23 +1331,26 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
int major = 0, minor = 0;
gint val;
- nvLayoutPtr layout;
nvDisplayPtr display;
Bool trust_slimm_available = FALSE;
Bool only_max;
- int hoverlap = 0;
- int voverlap = 0;
- /* now, create the object */
+ /* now, create the dialog */
+
+ ctk_mmdialog = calloc(1, sizeof(CtkMMDialog));
+ if (!ctk_mmdialog) {
+ return NULL;
+ }
- object = g_object_new(CTK_TYPE_SLIMM, NULL);
- ctk_slimm = CTK_SLIMM(object);
+ ctk_mmdialog->ctrl_target = ctrl_target;
+ ctk_mmdialog->ctk_config = ctk_config;
- ctk_slimm->ctrl_target = ctrl_target;
- ctk_slimm->ctk_config = ctk_config;
- ctk_object = ctk_slimm;
+ ctk_mmdialog->parent = parent;
+ ctk_mmdialog->layout = layout;
+
+ ctk_mmdialog->is_active = FALSE;
/*
* Check for NV-CONTROL protocol version.
@@ -1337,7 +1369,8 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
/* return on old X drivers. */
if (!trust_slimm_available) {
- return NULL;
+ free(ctk_mmdialog);
+ return NULL;
}
/* Check if this screen supports SLI Mosaic Mode */
@@ -1346,21 +1379,24 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
if ((ret == NvCtrlSuccess) &&
(val == NV_CTRL_SLI_MOSAIC_MODE_AVAILABLE_FALSE)) {
/* Mosaic not supported */
+ free(ctk_mmdialog);
return NULL;
}
/* Query the maximum screen sizes */
ret = NvCtrlGetAttribute(ctrl_target,
NV_CTRL_MAX_SCREEN_WIDTH,
- &ctk_slimm->max_screen_width);
+ &ctk_mmdialog->max_screen_width);
if (ret != NvCtrlSuccess) {
+ free(ctk_mmdialog);
return NULL;
}
ret = NvCtrlGetAttribute(ctrl_target,
NV_CTRL_MAX_SCREEN_HEIGHT,
- &ctk_slimm->max_screen_height);
+ &ctk_mmdialog->max_screen_height);
if (ret != NvCtrlSuccess) {
+ free(ctk_mmdialog);
return NULL;
}
@@ -1369,144 +1405,45 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
*
*/
- /* Load the layout structure from the X server */
- layout = layout_load_from_server(ctrl_target, &err_str);
-
- if (!err_str && layout) {
- nvGpuPtr gpu;
- int num_displays = 0;
-
- for (gpu = layout->gpus; gpu; gpu = gpu->next_in_layout) {
- num_displays += gpu->num_displays;
- }
-
- ctk_slimm->num_displays = num_displays;
-
-
- /* Make sure we have enough displays for the minimum config */
- if (num_displays < 2) {
- err_str = g_strdup_printf("Not enough display devices to "
- "configure SLI Mosaic Mode.\nYou must "
- "have at least 2 Displays connected, "
- "but only %d Display%s detected.",
- num_displays,
- (num_displays != 1) ? "s were" : " was");
- layout_free(layout);
- layout = NULL;
-
- } else {
- parse_slimm_layout(ctk_slimm,
- layout,
- &hoverlap,
- &voverlap);
- }
- }
+ err_str = count_displays_and_parse_layout(ctk_mmdialog);
/* If we failed to load, tell the user why */
if (err_str || !layout) {
- goto slimm_fail;
+ print_error_string(err_str);
+ g_free(err_str);
+ free(ctk_mmdialog);
+ return NULL;
}
- display = intersect_modelines(layout);
+ display = setup_display(ctk_mmdialog);
if (display == NULL) {
- err_str = g_strdup("Unable to find active display with "
- "intersected modelines.");
- goto slimm_fail;
- } else if ((display->modelines == NULL) &&
- (display->cur_mode->modeline == NULL)) {
- /* The modepool for the active display did not have any modes in
- * its modepool matching any of the modes on the modepool of any
- * other display in the layout, causing intersect_modelines to
- * remove every mode from the list of available modes for SLI mosaic
- * mode.
- *
- * This can happen if one display had its modepool trimmed and modified
- * to support 3D vision, while other displays (either on X screens
- * without stereo currently enabled, or on screenless GPUs) did not.
- * Find if that is the case, and display an informative message if so.
- */
- nvGpuPtr gpu;
- nvDisplayPtr d;
- int stereo = get_display_stereo_mode(display);
-
- for (gpu = layout->gpus; gpu; gpu = gpu->next_in_layout) {
- for (d = gpu->displays; d; d = d->next_on_gpu) {
- int other_stereo;
-
- if (display == d) {
- continue;
- }
-
- other_stereo = get_display_stereo_mode(d);
-
- if ((STEREO_IS_3D_VISION(stereo) &&
- !STEREO_IS_3D_VISION(other_stereo)) ||
- (!STEREO_IS_3D_VISION(stereo) &&
- STEREO_IS_3D_VISION(other_stereo))) {
-
- err_str = g_strdup("Unable to find common modelines between\n"
- "all connected displays due to 3D vision\n"
- "being enabled on some displays and not\n"
- "others. Please make sure that 3D vision\n"
- "is enabled on all connected displays\n"
- "before enabling SLI mosaic mode.");
-
- goto slimm_fail;
- }
- }
- }
-
- /* The intersected modepool was empty, but not because of a mismatch
- * in 3D Vision settings.
- */
- err_str = g_strdup("Unable to find find common modelines between "
- "all connected displays.");
-
- goto slimm_fail;
+ return NULL;
}
+ /* Create the dialog */
+ dialog_obj = gtk_dialog_new_with_buttons
+ ("Configure SLI Mosaic Layout",
+ GTK_WINDOW(gtk_widget_get_parent(GTK_WIDGET(parent))),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ "_Apply to Layout",
+ GTK_RESPONSE_APPLY,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ ctk_mmdialog->dialog = dialog_obj;
- /* Extract modelines and cur_modeline and free layout structure */
- ctk_object->modelines = display->modelines;
- if (display->cur_mode->modeline) {
- ctk_object->cur_modeline = display->cur_mode->modeline;
- } else {
- ctk_object->cur_modeline = ctk_object->modelines;
- }
- ctk_object->num_modelines = display->num_modelines;
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog_obj),
+ GTK_RESPONSE_REJECT);
- /* XXX Since we've hijacked the layout's modelines,
- * we can stub out the layout's pointer and free it.
- */
- display->modelines = NULL;
- display->cur_mode->modeline = NULL;
- display->num_modelines = 0;
- layout_free(layout);
- layout = NULL;
/* set container properties of the object */
- gtk_box_set_spacing(GTK_BOX(ctk_slimm), 10);
-
- /* banner */
-
- banner = ctk_banner_image_new(BANNER_ARTWORK_SLIMM);
- gtk_box_pack_start(GTK_BOX(ctk_slimm), banner, FALSE, FALSE, 0);
-
+ content = ctk_dialog_get_content_area(GTK_DIALOG(dialog_obj));
+ gtk_box_set_spacing(GTK_BOX(content), 10);
vbox = gtk_vbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(ctk_slimm), vbox, TRUE, TRUE, 0);
-
- hbox = gtk_hbox_new(FALSE, 0);
- checkbutton = gtk_check_button_new_with_label("Use SLI Mosaic Mode");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), TRUE);
- ctk_slimm->cbtn_slimm_enable = checkbutton;
- g_signal_connect(G_OBJECT(checkbutton), "toggled",
- G_CALLBACK(slimm_checkbox_toggled),
- (gpointer) ctk_object);
- gtk_box_pack_start(GTK_BOX(hbox), checkbutton, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(content), vbox);
hbox = gtk_hbox_new(FALSE, 0);
label = gtk_label_new("Display Configuration (rows x columns)");
@@ -1515,30 +1452,31 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
gtk_box_pack_start(GTK_BOX(hbox), hseparator, TRUE, TRUE, 10);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
+
hbox = gtk_hbox_new(FALSE, 0);
/* Option menu for Display Grid Configuration */
menu = (CtkDropDownMenu *)
ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
- ctk_slimm->mnu_display_config = GTK_WIDGET(menu);
+ ctk_mmdialog->mnu_display_config = GTK_WIDGET(menu);
- only_max = (ctk_slimm->parsed_rows * ctk_slimm->parsed_cols ==
- ctk_slimm->num_displays);
+ only_max = (ctk_mmdialog->parsed_rows * ctk_mmdialog->parsed_cols ==
+ ctk_mmdialog->num_displays);
- populate_dropdown(ctk_slimm, only_max);
+ populate_dropdown(ctk_mmdialog, only_max);
- g_signal_connect(G_OBJECT(ctk_object->mnu_display_config), "changed",
+ g_signal_connect(G_OBJECT(ctk_mmdialog->mnu_display_config), "changed",
G_CALLBACK(display_config_changed),
- (gpointer) ctk_object);
+ (gpointer) ctk_mmdialog);
checkbutton = gtk_check_button_new_with_label("Only show configurations "
"using all displays");
+ ctk_mmdialog->chk_all_displays = checkbutton;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), only_max);
g_signal_connect(G_OBJECT(checkbutton), "toggled",
G_CALLBACK(restrict_display_config_changed),
- (gpointer) ctk_object);
+ (gpointer) ctk_mmdialog);
label = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
@@ -1574,34 +1512,34 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
/* Option menu for resolutions */
hbox = gtk_hbox_new(FALSE, 0);
- ctk_slimm->mnu_display_resolution =
+ ctk_mmdialog->mnu_display_resolution =
ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
/* Create a drop down menu */
- setup_display_resolution_dropdown(ctk_object);
+ setup_display_resolution_dropdown(ctk_mmdialog);
label = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
- gtk_box_pack_end(GTK_BOX(hbox), ctk_slimm->mnu_display_resolution,
+ gtk_box_pack_end(GTK_BOX(hbox), ctk_mmdialog->mnu_display_resolution,
TRUE, TRUE, 0);
gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0.5, 0.5);
- g_signal_connect(G_OBJECT(ctk_object->mnu_display_resolution), "changed",
+ g_signal_connect(G_OBJECT(ctk_mmdialog->mnu_display_resolution), "changed",
G_CALLBACK(display_resolution_changed),
- (gpointer) ctk_object);
+ (gpointer) ctk_mmdialog);
/* Option menu for refresh rates */
hbox = gtk_hbox_new(FALSE, 0);
- ctk_slimm->mnu_display_refresh =
+ ctk_mmdialog->mnu_display_refresh =
ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_READONLY);
- setup_display_refresh_dropdown(ctk_object);
- g_signal_connect(G_OBJECT(ctk_object->mnu_display_refresh), "changed",
+ setup_display_refresh_dropdown(ctk_mmdialog);
+ g_signal_connect(G_OBJECT(ctk_mmdialog->mnu_display_refresh), "changed",
G_CALLBACK(display_refresh_changed),
- (gpointer) ctk_object);
+ (gpointer) ctk_mmdialog);
label = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
- gtk_box_pack_end(GTK_BOX(hbox), ctk_slimm->mnu_display_refresh, TRUE, TRUE, 0);
+ gtk_box_pack_end(GTK_BOX(hbox), ctk_mmdialog->mnu_display_refresh, TRUE, TRUE, 0);
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 3, 4, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0.5, 0.5);
@@ -1631,16 +1569,18 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
label = gtk_label_new("Horizontal:");
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
- spinbutton = gtk_spin_button_new_with_range(-ctk_object->cur_modeline->data.hdisplay,
- ctk_object->cur_modeline->data.hdisplay,
- 1);
+ spinbutton = gtk_spin_button_new_with_range(
+ -ctk_mmdialog->cur_modeline->data.hdisplay,
+ ctk_mmdialog->cur_modeline->data.hdisplay,
+ 1);
- ctk_slimm->spbtn_hedge_overlap = spinbutton;
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton), hoverlap);
+ ctk_mmdialog->spbtn_hedge_overlap = spinbutton;
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton),
+ ctk_mmdialog->h_overlap_parsed);
- g_signal_connect(G_OBJECT(ctk_object->spbtn_hedge_overlap), "value-changed",
+ g_signal_connect(G_OBJECT(ctk_mmdialog->spbtn_hedge_overlap), "value-changed",
G_CALLBACK(txt_overlap_activated),
- (gpointer) ctk_object);
+ (gpointer) ctk_mmdialog);
gtk_box_pack_start(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 5);
@@ -1655,15 +1595,16 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
label = gtk_label_new("Vertical: ");
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
- spinbutton = gtk_spin_button_new_with_range(-ctk_object->cur_modeline->data.vdisplay,
- ctk_object->cur_modeline->data.vdisplay,
+ spinbutton = gtk_spin_button_new_with_range(-ctk_mmdialog->cur_modeline->data.vdisplay,
+ ctk_mmdialog->cur_modeline->data.vdisplay,
1);
- ctk_slimm->spbtn_vedge_overlap = spinbutton;
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton), voverlap);
+ ctk_mmdialog->spbtn_vedge_overlap = spinbutton;
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbutton),
+ ctk_mmdialog->v_overlap_parsed);
- g_signal_connect(G_OBJECT(ctk_object->spbtn_vedge_overlap), "value-changed",
+ g_signal_connect(G_OBJECT(ctk_mmdialog->spbtn_vedge_overlap), "value-changed",
G_CALLBACK(txt_overlap_activated),
- (gpointer) ctk_object);
+ (gpointer) ctk_mmdialog);
gtk_box_pack_start(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 5);
@@ -1674,11 +1615,11 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
GTK_EXPAND | GTK_FILL, 0.5, 0.5);
label = gtk_label_new("NULL");
- ctk_slimm->lbl_total_size = label;
- setup_total_size_label(ctk_slimm);
+ ctk_mmdialog->lbl_total_size = label;
+ setup_total_size_label(ctk_mmdialog);
hbox = gtk_hbox_new(FALSE, 0);
- ctk_slimm->box_total_size = hbox;
+ ctk_mmdialog->box_total_size = hbox;
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 9, 10, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0.5, 0.5);
@@ -1692,8 +1633,8 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 10, 11, GTK_EXPAND | GTK_FILL,
GTK_EXPAND | GTK_FILL, 0.5, 0.5);
- tmp = g_strdup_printf("%dx%d", ctk_slimm->max_screen_width,
- ctk_slimm->max_screen_height);
+ tmp = g_strdup_printf("%dx%d", ctk_mmdialog->max_screen_width,
+ ctk_mmdialog->max_screen_height);
label = gtk_label_new(tmp);
g_free(tmp);
hbox = gtk_hbox_new(FALSE, 0);
@@ -1702,116 +1643,51 @@ GtkWidget* ctk_slimm_new(CtrlTarget *ctrl_target,
GTK_EXPAND | GTK_FILL, 0.5, 0.5);
- label = gtk_label_new("Save to X Configuration File");
- hbox = gtk_hbox_new(FALSE, 0);
- button = gtk_button_new();
- ctk_slimm->btn_save_config = button;
- g_signal_connect(G_OBJECT(ctk_object->btn_save_config), "clicked",
- G_CALLBACK(save_xconfig_button_clicked),
- (gpointer) ctk_object);
-
- ctk_slimm->save_xconfig_dlg =
- create_save_xconfig_dialog(GTK_WIDGET(ctk_slimm),
- FALSE, // Merge toggleable
- xconfig_generate,
- (void *)ctk_slimm);
-
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- gtk_container_add(GTK_CONTAINER(button), hbox);
-
- gtk_table_attach(GTK_TABLE(table), button, 1, 2, 19, 20, GTK_EXPAND | GTK_FILL,
- GTK_EXPAND | GTK_FILL, 0, 0);
-
/* If current SLI Mode != Mosaic, disable UI elements initially */
ret = NvCtrlGetStringAttribute(ctrl_target,
NV_CTRL_STRING_SLI_MODE,
&sli_mode);
- set_overlap_controls_status(ctk_slimm);
-
- if ((ret != NvCtrlSuccess) ||
- (ret == NvCtrlSuccess && g_ascii_strcasecmp(sli_mode, "Mosaic"))) {
- gtk_toggle_button_set_active(
- GTK_TOGGLE_BUTTON(ctk_slimm->cbtn_slimm_enable), FALSE);
- slimm_checkbox_toggled(ctk_slimm->cbtn_slimm_enable,
- (gpointer) ctk_slimm);
- }
+ set_overlap_controls_status(ctk_mmdialog);
- ctk_object->ctk_config->pending_config &=
+ ctk_mmdialog->ctk_config->pending_config &=
~CTK_CONFIG_PENDING_WRITE_MOSAIC_CONFIG;
free(sli_mode);
- gtk_widget_show_all(GTK_WIDGET(object));
-
- return GTK_WIDGET(object);
-
-slimm_fail:
-
- if (layout) {
- layout_free(layout);
- }
-
- if (!err_str) {
- str = g_strdup("Unable to load SLI Mosaic Mode Settings page.");
- } else {
- str = g_strdup_printf("Unable to load SLI Mosaic Mode Settings "
- "page:\n\n%s", err_str);
- g_free(err_str);
- }
-
- label = gtk_label_new(str);
- g_free(str);
- gtk_label_set_selectable(GTK_LABEL(label), TRUE);
- gtk_container_add(GTK_CONTAINER(object), label);
-
- /* Show the GUI */
- gtk_widget_show_all(GTK_WIDGET(ctk_object));
-
- return GTK_WIDGET(ctk_object);
+ gtk_widget_show_all(content);
+ return ctk_mmdialog;
}
-
-GtkTextBuffer *ctk_slimm_create_help(GtkTextTagTable *table,
- const gchar *slimm_name)
-{
- GtkTextIter i;
- GtkTextBuffer *b;
-
- b = gtk_text_buffer_new(table);
-
- gtk_text_buffer_get_iter_at_offset(b, &i, 0);
- ctk_help_title(b, &i, "SLI Mosaic Mode Settings Help");
+void ctk_mmdialog_insert_help(GtkTextBuffer *b, GtkTextIter *i)
+{
+ ctk_help_heading(b, i, "Configure SLI Mosaic Layout Dialog");
- ctk_help_para(b, &i, "This page allows easy configuration "
+ ctk_help_para(b, i, "This dialog allows easy configuration "
"of SLI Mosaic Mode.");
- ctk_help_heading(b, &i, "Use SLI Mosaic Mode");
- ctk_help_para(b, &i, "This checkbox controls whether SLI Mosaic Mode is enabled "
- "or disabled.");
-
- ctk_help_heading(b, &i, "Display Configuration");
- ctk_help_para(b, &i, "This drop down menu allows selection of the display grid "
+ ctk_help_heading(b, i, "Display Configuration");
+ ctk_help_para(b, i, "This drop down menu allows selection of the display grid "
"configuration for SLI Mosaic Mode; the possible configurations "
"are described as rows x columns.");
- ctk_help_heading(b, &i, "Resolution");
- ctk_help_para(b, &i, "This drop down menu allows selection of the resolution to "
+ ctk_help_heading(b, i, "Resolution");
+ ctk_help_para(b, i, "This drop down menu allows selection of the resolution to "
"use for each of the displays in SLI Mosaic Mode. Note that only "
"the resolutions that are available for each display will be "
"shown here.");
- ctk_help_heading(b, &i, "Refresh Rate");
- ctk_help_para(b, &i, "This drop down menu allows selection of the refresh rate "
+ ctk_help_heading(b, i, "Refresh Rate");
+ ctk_help_para(b, i, "This drop down menu allows selection of the refresh rate "
"to use for each of the displays in SLI Mosaic Mode. By default "
"the highest refresh rate each of the displays can achieve at "
"the selected resolution is chosen. This combo box gets updated "
"when a new resolution is picked.");
- ctk_help_heading(b, &i, "Edge Overlap");
- ctk_help_para(b, &i, "These two controls allow the user to specify the "
+ ctk_help_heading(b, i, "Edge Overlap");
+ ctk_help_para(b, i, "These two controls allow the user to specify the "
"Horizontal and Vertical Edge Overlap values. The displays "
"will overlap by the specified number of pixels when forming "
"the grid configuration. For example, 4 flat panel displays "
@@ -1820,21 +1696,93 @@ GtkTextBuffer *ctk_slimm_create_help(GtkTextTagTable *table,
"will generate the following MetaMode: \"1600x1200+0+0,"
"1600x1200+1550+0,1600x1200+0+1150,1600x1200+1550+1150\".");
- ctk_help_heading(b, &i, "Total Size");
- ctk_help_para(b, &i, "This is the total size of the X screen formed using all "
+ ctk_help_heading(b, i, "Total Size");
+ ctk_help_para(b, i, "This is the total size of the X screen formed using all "
"displays in SLI Mosaic Mode.");
- ctk_help_heading(b, &i, "Maximum Size");
- ctk_help_para(b, &i, "This is the maximum allowable size of the X screen "
+ ctk_help_heading(b, i, "Maximum Size");
+ ctk_help_para(b, i, "This is the maximum allowable size of the X screen "
"formed using all displays in SLI Mosaic Mode.");
- ctk_help_heading(b, &i, "Save to X Configuration File");
- ctk_help_para(b, &i, "Clicking this button saves the selected SLI Mosaic Mode "
- "settings into the X Configuration File.");
+}
+
+
+
+int run_mosaic_dialog(CtkMMDialog *ctk_mmdialog, GtkWidget *parent,
+ const nvLayoutPtr layout)
+{
+ gint response;
+ gint x_displays, y_displays;
+ CtkDropDownMenu *menu;
+ gint idx;
+ gint h_overlap;
+ gint v_overlap;
+
+
+ ctk_mmdialog->layout = layout;
+
+ /* Show the save dialog */
+ gtk_window_set_transient_for
+ (GTK_WINDOW(ctk_mmdialog->dialog),
+ GTK_WINDOW(gtk_widget_get_toplevel(parent)));
+
+ gtk_window_resize(GTK_WINDOW(ctk_mmdialog->dialog), 350, 1);
+ gtk_window_set_resizable(GTK_WINDOW(ctk_mmdialog->dialog), FALSE);
+ gtk_widget_show(ctk_mmdialog->dialog);
+
+ ctk_mmdialog->is_active = TRUE;
+ response = gtk_dialog_run(GTK_DIALOG(ctk_mmdialog->dialog));
+ ctk_mmdialog->is_active = FALSE;
+
+ gtk_widget_hide(ctk_mmdialog->dialog);
+
+ if (response == GTK_RESPONSE_ACCEPT ||
+ response == GTK_RESPONSE_APPLY) {
+
+
+ /* Grid width && Grid height */
+
+ menu = CTK_DROP_DOWN_MENU(ctk_mmdialog->mnu_display_config);
+ idx = ctk_drop_down_menu_get_current_value(menu);
+
+ if (idx < ctk_mmdialog->num_grid_configs) {
+ x_displays = ctk_mmdialog->grid_configs[idx].columns;
+ y_displays = ctk_mmdialog->grid_configs[idx].rows;
+ } else {
+ x_displays = y_displays = 0;
+ }
+
+ ctk_mmdialog->x_displays = x_displays;
+ ctk_mmdialog->y_displays = y_displays;
+
+
+ /* Resolution */
+
+ menu = CTK_DROP_DOWN_MENU(ctk_mmdialog->mnu_display_resolution);
+ ctk_mmdialog->resolution_idx =
+ ctk_drop_down_menu_get_current_value(menu);
+
+
+ /* Refresh Rate */
+
+ menu = CTK_DROP_DOWN_MENU(ctk_mmdialog->mnu_display_refresh);
+ ctk_mmdialog->refresh_idx = ctk_drop_down_menu_get_current_value(menu);
+
+
+ /* Edge Overlap */
+
+ h_overlap = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(ctk_mmdialog->spbtn_hedge_overlap));
+ v_overlap = gtk_spin_button_get_value_as_int(
+ GTK_SPIN_BUTTON(ctk_mmdialog->spbtn_vedge_overlap));
+
+ ctk_mmdialog->h_overlap = h_overlap;
+ ctk_mmdialog->v_overlap = v_overlap;
+
+ }
- ctk_help_finish(b);
+ return response != GTK_RESPONSE_CANCEL;
- return b;
}
diff --git a/src/gtk+-2.x/ctkslimm.h b/src/gtk+-2.x/ctkslimm.h
index 00fd283..277d818 100644
--- a/src/gtk+-2.x/ctkslimm.h
+++ b/src/gtk+-2.x/ctkslimm.h
@@ -29,40 +29,27 @@
#include "XF86Config-parser/xf86Parser.h"
-G_BEGIN_DECLS
-
-#define CTK_TYPE_SLIMM (ctk_slimm_get_type())
-
-#define CTK_SLIMM(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), CTK_TYPE_SLIMM, CtkSLIMM))
-
-#define CTK_SLIMM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), CTK_TYPE_SLIMM, CtkSLIMMClass))
-
-#define CTK_IS_SLIMM(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CTK_TYPE_SLIMM))
-
-#define CTK_IS_SLIMM_CLASS(class) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), CTK_TYPE_SLIMM))
-
-#define CTK_SLIMM_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), CTK_TYPE_SLIMM, CtkSLIMMClass))
-
-typedef struct _CtkSLIMM CtkSLIMM;
-typedef struct _CtkSLIMMClass CtkSLIMMClass;
-
typedef struct GridConfigRec {
int rows;
int columns;
} GridConfig;
-struct _CtkSLIMM
+typedef struct nvModeLineItemRec {
+ nvModeLinePtr modeline;
+ struct nvModeLineItemRec *next;
+} nvModeLineItem, *nvModeLineItemPtr;
+
+typedef struct _CtkMMDialog
{
- GtkVBox parent;
+ GtkWidget *parent;
+ nvLayoutPtr layout;
CtrlTarget *ctrl_target;
CtkConfig *ctk_config;
+ GtkWidget *dialog;
+ gboolean is_active;
+
GtkWidget *mnu_display_config;
GtkWidget *mnu_display_resolution;
GtkWidget *mnu_display_refresh;
@@ -70,15 +57,15 @@ struct _CtkSLIMM
GtkWidget *spbtn_vedge_overlap;
GtkWidget *lbl_total_size;
GtkWidget *box_total_size;
- GtkWidget *btn_save_config;
- SaveXConfDlg *save_xconfig_dlg;
- GtkWidget *cbtn_slimm_enable;
+ GtkWidget *chk_all_displays;
nvModeLinePtr *resolution_table;
nvModeLinePtr *refresh_table;
int resolution_table_len;
int refresh_table_len;
+ int cur_resolution_table_idx;
+ gint h_overlap_parsed, v_overlap_parsed;
gboolean mnu_refresh_disabled;
- nvModeLinePtr modelines;
+ nvModeLineItemPtr modelines;
nvModeLinePtr cur_modeline;
gint num_modelines;
int num_displays;
@@ -88,6 +75,10 @@ struct _CtkSLIMM
int max_screen_width;
int max_screen_height;
+ gint x_displays, y_displays;
+ gint resolution_idx, refresh_idx;
+ gint h_overlap, v_overlap;
+
/**
* The grid_configs array enumerates the display grid configurations
* that are presently supported.
@@ -95,20 +86,15 @@ struct _CtkSLIMM
GridConfig *grid_configs;
int num_grid_configs;
-};
-
-struct _CtkSLIMMClass
-{
- GtkVBoxClass parent_class;
-};
-
-GType ctk_slimm_get_type (void) G_GNUC_CONST;
-GtkWidget* ctk_slimm_new (CtrlTarget *ctrl_target,
- CtkEvent *ctk_event, CtkConfig *ctk_config);
+} CtkMMDialog;
-GtkTextBuffer *ctk_slimm_create_help(GtkTextTagTable *, const gchar *);
+CtkMMDialog *create_mosaic_dialog(GtkWidget *parent, CtrlTarget *ctrl_target,
+ CtkConfig *ctk_config, nvLayoutPtr layout);
+int run_mosaic_dialog(CtkMMDialog *dialog, GtkWidget *parent,
+ nvLayoutPtr layout);
-G_END_DECLS
+void ctk_mmdialog_insert_help(GtkTextBuffer *b, GtkTextIter *i);
+void update_mosaic_dialog_ui(CtkMMDialog *ctk_mmdialog, nvLayoutPtr layout);
#endif /* __CTK_SLIMM_H__ */
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index dd9a8a4..a208055 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -503,7 +503,6 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
CtkConfig *ctk_config;
gint column_offset;
- gboolean slimm_page_added; /* XXX Kludge to only show one SLIMM page */
/* create the new object */
@@ -697,7 +696,6 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
/* add the per-screen entries into the tree model */
- slimm_page_added = FALSE;
for (node = system->targets[X_SCREEN_TARGET]; node; node = node->next) {
gchar *screen_name;
@@ -738,18 +736,6 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
CTK_WINDOW_CONFIG_FILE_ATTRIBUTES_FUNC_COLUMN,
NULL, -1);
- if (!slimm_page_added) {
- /* SLI Mosaic Mode information */
-
- child = ctk_slimm_new(screen_target, ctk_event, ctk_config);
- if (child) {
- slimm_page_added = TRUE;
- help = ctk_slimm_create_help(tag_table, "SLI Mosaic Mode Settings");
- add_page(child, help, ctk_window, &iter, NULL,
- "SLI Mosaic Mode Settings", NULL, NULL, NULL);
- }
- }
-
/*
* color correction, if RandR per-CRTC color correction is not
* available
diff --git a/src/libXNVCtrl/version.mk b/src/libXNVCtrl/version.mk
index 618e84a..14d7f22 100644
--- a/src/libXNVCtrl/version.mk
+++ b/src/libXNVCtrl/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 455.23.04
+NVIDIA_VERSION = 455.28
diff --git a/src/nvml.h b/src/nvml.h
index 668f499..56c81e0 100644
--- a/src/nvml.h
+++ b/src/nvml.h
@@ -904,6 +904,8 @@ typedef enum {
#define NVML_GRID_LICENSE_FEATURE_MAX_COUNT 3
+#define INVALID_GPU_INSTANCE_PROFILE_ID 0xFFFFFFFF
+
/*!
* Macros for vGPU instance's virtualization capabilities bitfield.
*/
@@ -5985,6 +5987,24 @@ nvmlReturn_t DECLDIR nvmlVgpuTypeGetClass(nvmlVgpuTypeId_t vgpuTypeId, char *vgp
nvmlReturn_t DECLDIR nvmlVgpuTypeGetName(nvmlVgpuTypeId_t vgpuTypeId, char *vgpuTypeName, unsigned int *size);
/**
+ * Retrieve the GPU Instance Profile ID for the given vGPU type ID.
+ * The API will return a valid profile ID for MIG backed vGPU types when GPU is configured in MIG mode, else INVALID_GPU_INSTANCE_PROFILE_ID
+ * is returned.
+ *
+ * For Kepler &tm; or newer fully supported devices.
+ *
+ * @param vgpuTypeId Handle to vGPU type
+ * @param gpuInstanceProfileId GPU instance Profile ID
+ *
+ * @return
+ * - \ref NVML_SUCCESS successful completion
+ * - \ref NVML_ERROR_NOT_SUPPORTED if \a device is not in vGPU Host virtualization mode
+ * - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a vgpuTypeId is invalid, or \a gpuInstanceProfileId is NULL
+ * - \ref NVML_ERROR_UNKNOWN on any unexpected error
+ */
+nvmlReturn_t DECLDIR nvmlVgpuTypeGetGpuInstanceProfileId(nvmlVgpuTypeId_t vgpuTypeId, unsigned int *gpuInstanceProfileId);
+
+/**
* Retrieve the device ID of a vGPU type.
*
* For Kepler &tm; or newer fully supported devices.
diff --git a/src/version.h b/src/version.h
index e9b7758..7f42b14 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1 +1 @@
-#define NVIDIA_VERSION "455.23.04"
+#define NVIDIA_VERSION "455.28"
diff --git a/src/version.mk b/src/version.mk
index 618e84a..14d7f22 100644
--- a/src/version.mk
+++ b/src/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 455.23.04
+NVIDIA_VERSION = 455.28
diff --git a/version.mk b/version.mk
index 618e84a..14d7f22 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 455.23.04
+NVIDIA_VERSION = 455.28