summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2012-11-13 12:23:33 -0800
committerAaron Plattner <aplattner@nvidia.com>2012-11-13 12:23:33 -0800
commite9f8e835f4e9ac4c59383feed05bb055d3405bf4 (patch)
tree07eaa2367b0547fd3b739e420dc028b98b0aefcd
parent6f881b3f5e7701b9071f7dcf68d608b60472deed (diff)
310.19310.19
-rw-r--r--doc/version.mk2
-rw-r--r--samples/version.mk2
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.c46
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.h3
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig-utils.c425
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig-utils.h3
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c803
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.h17
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice.c6
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice.h2
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.c407
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.h47
-rw-r--r--src/gtk+-2.x/ctkevent.c7
-rw-r--r--src/gtk+-2.x/ctkgpu.c106
-rw-r--r--src/gtk+-2.x/ctkgpu.h5
-rw-r--r--src/gtk+-2.x/ctkmultisample.c10
-rw-r--r--src/gtk+-2.x/ctkscreen.c1
-rw-r--r--src/gtk+-2.x/ctkwindow.c6
-rw-r--r--src/libXNVCtrl/NVCtrl.h52
-rw-r--r--src/parse.c4
-rw-r--r--src/version.mk2
-rw-r--r--version.mk2
22 files changed, 1608 insertions, 350 deletions
diff --git a/doc/version.mk b/doc/version.mk
index 1feef56..6db0208 100644
--- a/doc/version.mk
+++ b/doc/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 310.14
+NVIDIA_VERSION = 310.19
diff --git a/samples/version.mk b/samples/version.mk
index 1feef56..6db0208 100644
--- a/samples/version.mk
+++ b/samples/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 310.14
+NVIDIA_VERSION = 310.19
diff --git a/src/gtk+-2.x/ctkcolorcorrection.c b/src/gtk+-2.x/ctkcolorcorrection.c
index 8abfb8e..de96242 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.c
+++ b/src/gtk+-2.x/ctkcolorcorrection.c
@@ -1040,11 +1040,28 @@ GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table,
ctk_help_title(b, &i, "%s Help", title);
- ctk_help_heading(b, &i, "Active Color Channel");
- ctk_help_para(b, &i, __active_color_help);
+ ctk_color_correction_tab_help(b, &i, title, randr);
+
+ ctk_help_heading(b, &i, "Reset Hardware Defaults");
+ ctk_help_para(b, &i, __resest_button_help);
+
+ ctk_help_finish(b);
+
+ return b;
+}
+
+
+void ctk_color_correction_tab_help(GtkTextBuffer *b, GtkTextIter *i,
+ const gchar *title,
+ gboolean randr)
+{
+ ctk_help_heading(b, i, "Color Correction");
- ctk_help_heading(b, &i, "Brightness, Contrast and Gamma");
- ctk_help_para(b, &i, "The Brightness, Contrast and Gamma sliders "
+ ctk_help_term(b, i, "Active Color Channel");
+ ctk_help_para(b, i, __active_color_help);
+
+ ctk_help_term(b, i, "Brightness, Contrast and Gamma");
+ ctk_help_para(b, i, "The Brightness, Contrast and Gamma sliders "
"allow you to adjust the brightness, contrast, "
"or gamma values for the selected color channel(s). This "
"helps you to compensate "
@@ -1055,28 +1072,21 @@ GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table,
"as photographs) when they are displayed on your "
"monitor.");
- ctk_help_para(b, &i, "Also, many 3D-accelerated games may appear too "
+ ctk_help_para(b, i, "Also, many 3D-accelerated games may appear too "
"dark to play. Increasing the brightness and/or gamma "
"value equally across all channels will make these games "
"appear brighter, making them more playable.");
-
- ctk_help_para(b, &i, __color_curve_help);
+
+ ctk_help_para(b, i, __color_curve_help);
if (randr) {
- ctk_help_para(b, &i, "The %s tab uses the RandR extension to "
+ ctk_help_para(b, i, "The %s tab uses the RandR extension to "
"manipulate an RandR CRTC's gamma ramp.", title);
} else {
- ctk_help_para(b, &i, "The %s page uses the XF86VidMode extension "
+ ctk_help_para(b, i, "The %s page uses the XF86VidMode extension "
"to manipulate the X screen's gamma ramps", title);
}
- ctk_help_heading(b, &i, "Confirm Current Changes");
- ctk_help_para(b, &i, __confirm_button_help);
-
- ctk_help_heading(b, &i, "Reset Hardware Defaults");
- ctk_help_para(b, &i, __resest_button_help);
-
- ctk_help_finish(b);
-
- return b;
+ ctk_help_term(b, i, "Confirm Current Changes");
+ ctk_help_para(b, i, __confirm_button_help);
}
diff --git a/src/gtk+-2.x/ctkcolorcorrection.h b/src/gtk+-2.x/ctkcolorcorrection.h
index 53cb36e..c9dfe48 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.h
+++ b/src/gtk+-2.x/ctkcolorcorrection.h
@@ -82,6 +82,9 @@ GtkWidget* ctk_color_correction_new (NvCtrlAttributeHandle *,
GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *,
const gchar *title,
gboolean randr);
+void ctk_color_correction_tab_help(GtkTextBuffer *b, GtkTextIter *i,
+ const gchar *title,
+ gboolean randr);
G_END_DECLS
#endif /* __CTK_COLOR_CORRECTION_H__ */
diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.c b/src/gtk+-2.x/ctkdisplayconfig-utils.c
index bb0ff6a..78ddf58 100644
--- a/src/gtk+-2.x/ctkdisplayconfig-utils.c
+++ b/src/gtk+-2.x/ctkdisplayconfig-utils.c
@@ -435,6 +435,93 @@ static nvModeLinePtr modeline_parse(nvDisplayPtr display,
/** MODE FUNCTIONS ***********************************************************/
/*****************************************************************************/
+void mode_set_dims_from_modeline(nvModePtr mode, nvModeLinePtr modeline)
+{
+ int newW;
+ int newH;
+
+
+ mode->viewPortOut[X] = 0;
+ mode->viewPortOut[Y] = 0;
+ if (modeline) {
+ mode->viewPortOut[W] = modeline->data.hdisplay;
+ mode->viewPortOut[H] = modeline->data.vdisplay;
+ } else {
+ mode->viewPortOut[W] = 800;
+ mode->viewPortOut[H] = 600;
+ }
+
+ /* Determine new dimensions to use */
+ if ((mode->rotation == ROTATION_90) ||
+ (mode->rotation == ROTATION_270)) {
+ newW = mode->viewPortOut[H];
+ newH = mode->viewPortOut[W];
+ } else {
+ newW = mode->viewPortOut[W];
+ newH = mode->viewPortOut[H];
+ }
+
+ /* Resolve and clamp the panning domain */
+ if ((mode->pan[W] == mode->viewPortIn[W]) ||
+ mode->pan[W] < newW) {
+ mode->pan[W] = newW;
+ }
+ if ((mode->pan[H] == mode->viewPortIn[H]) ||
+ mode->pan[H] < newH) {
+ mode->pan[H] = newH;
+ }
+ mode->viewPortIn[W] = newW;
+ mode->viewPortIn[H] = newH;
+}
+
+
+/*!
+ * Sets the mode to have the specified rotation
+ *
+ * \param[in] mode The mode to modify
+ * \param[in] rotation The rotation to set
+ *
+ * \return TRUE if a new rotation was set, FALSE if the mode was already
+ * set to the rotation given.
+ */
+Bool mode_set_rotation(nvModePtr mode, Rotation rotation)
+{
+ Bool old_is_horiz;
+ Bool new_is_horiz;
+ int tmp;
+
+ if (mode->rotation == rotation) {
+ return FALSE;
+ }
+
+ /* Set the new rotation orientation and swap if we need to*/
+ old_is_horiz = ((mode->rotation == ROTATION_0) ||
+ (mode->rotation == ROTATION_180)) ? TRUE : FALSE;
+
+ new_is_horiz = ((rotation == ROTATION_0) ||
+ (rotation == ROTATION_180)) ? TRUE : FALSE;
+
+ mode->rotation = rotation;
+
+ if (old_is_horiz != new_is_horiz) {
+ tmp = mode->viewPortIn[W];
+ mode->viewPortIn[W] = mode->viewPortIn[H];
+ mode->viewPortIn[H] = tmp;
+
+ tmp = mode->pan[W];
+ mode->pan[W] = mode->pan[H];
+ mode->pan[H] = tmp;
+ }
+
+ /* Mark mode as being modified */
+ if (mode->metamode) {
+ mode->metamode->source = METAMODE_SOURCE_NVCONTROL;
+ }
+
+ return TRUE;
+}
+
+
/** apply_mode_attribute_token() *************************************
*
@@ -460,7 +547,52 @@ static void apply_mode_attribute_token(char *token, char *value, void *data)
} else if (!strcasecmp("PassiveRight", value)) {
mode->passive_stereo_eye = PASSIVE_STEREO_EYE_RIGHT;
}
- return;
+
+ /* ViewPort In */
+ } else if (!strcasecmp("viewportin", token)) {
+ parse_read_integer_pair(value, 'x',
+ &(mode->viewPortIn[W]),
+ &(mode->viewPortIn[H]));
+
+ /* ViewPort Out */
+ } else if (!strcasecmp("viewportout", token)) {
+ const char *str;
+
+ str = parse_read_integer_pair(value, 'x',
+ &(mode->viewPortOut[W]),
+ &(mode->viewPortOut[H]));
+
+ str = parse_read_integer_pair(str, 0,
+ &(mode->viewPortOut[X]),
+ &(mode->viewPortOut[Y]));
+ }
+
+ /* Rotation */
+ if (!strcasecmp("rotation", token)) {
+ if (!strcasecmp("left", value) ||
+ !strcasecmp("CCW", value) ||
+ !strcasecmp("90", value)) {
+ mode->rotation = ROTATION_90;
+ } else if (!strcasecmp("invert", value) ||
+ !strcasecmp("inverted", value) ||
+ !strcasecmp("180", value)) {
+ mode->rotation = ROTATION_180;
+ } else if (!strcasecmp("right", value) ||
+ !strcasecmp("CW", value) ||
+ !strcasecmp("270", value)) {
+ mode->rotation = ROTATION_270;
+ }
+ }
+
+ /* Reflection */
+ if (!strcasecmp("reflection", token)) {
+ if (!strcasecmp("x", value)) {
+ mode->reflection = REFLECTION_X;
+ } else if (!strcasecmp("y", value)) {
+ mode->reflection = REFLECTION_Y;
+ } else if (!strcasecmp("xy", value)) {
+ mode->reflection = REFLECTION_XY;
+ }
}
} /* apply_mode_attribute_token() */
@@ -495,6 +627,12 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str)
mode->display = display;
+ /* Set default values */
+ mode->rotation = ROTATION_0;
+ mode->reflection = REFLECTION_NONE;
+ mode->passive_stereo_eye = PASSIVE_STEREO_EYE_NONE;
+ mode->position_type = CONF_ADJ_ABSOLUTE;
+
/* Read the mode name */
str = parse_read_name(str, &mode_name, 0);
@@ -509,12 +647,11 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str)
}
mode->modeline = mode->modeline->next;
}
- free(mode_name);
-
- /* If we can't find a matching modeline, show device as off
- * using the width & height of whatever the first modeline is.
- * XXX Hopefully this is the default width/height.
+ /* If we can't find a matching modeline, don't add this mode. If the
+ * metamode has other (valid) displays, a NULL mode will be added for this
+ * display at that time - this is done to avoid potentially adding a
+ * metamode with no active displays.
*/
if (!mode->modeline) {
if (strcmp(mode_str, "NULL")) {
@@ -522,19 +659,17 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str)
"display device '%s' in modeline '%s'.",
mode_name, display->logName, mode_str);
}
- mode->dim[W] = display->modelines->data.hdisplay;
- mode->dim[H] = display->modelines->data.vdisplay;
- mode->pan[W] = mode->dim[W];
- mode->pan[H] = mode->dim[H];
+ free(mode_name);
+
+ mode_set_dims_from_modeline(mode, display->modelines);
+
return mode;
}
+ free(mode_name);
- /* Setup default size and panning of display */
- mode->dim[W] = mode->modeline->data.hdisplay;
- mode->dim[H] = mode->modeline->data.vdisplay;
- mode->pan[W] = mode->dim[W];
- mode->pan[H] = mode->dim[H];
+ /* Setup default size and panning of display values */
+ mode_set_dims_from_modeline(mode, mode->modeline);
/* Read mode information */
@@ -551,7 +686,8 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str)
else if (*str == '+') {
str++;
str = parse_read_integer_pair(str, 0,
- &(mode->dim[X]), &(mode->dim[Y]));
+ &(mode->viewPortIn[X]),
+ &(mode->viewPortIn[Y]));
}
/* Read extra params */
@@ -584,18 +720,25 @@ nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str)
if (!str) goto fail;
}
+ /* If rotation is specified, swap W/H if they are still set to the
+ * modeline's unrotated dimentions. Panning should not be rotated
+ * here since it is returned rotated by the X driver.
+ */
+ if (((mode->rotation == ROTATION_90) ||
+ (mode->rotation == ROTATION_270)) &&
+ (mode->viewPortIn[W] == mode->viewPortOut[W]) &&
+ (mode->viewPortIn[H] == mode->viewPortOut[H])) {
+ int tmp = mode->viewPortIn[W];
+ mode->viewPortIn[W] = mode->viewPortIn[H];
+ mode->viewPortIn[H] = tmp;
+ }
- /* These are the same for now */
- mode->pan[X] = mode->dim[X];
- mode->pan[Y] = mode->dim[Y];
-
-
- /* Panning can't be smaller than dimensions */
- if (mode->pan[W] < mode->dim[W]) {
- mode->pan[W] = mode->dim[W];
+ /* Clamp the panning domain */
+ if (mode->pan[W] < mode->viewPortIn[W]) {
+ mode->pan[W] = mode->viewPortIn[W];
}
- if (mode->pan[W] < mode->dim[W]) {
- mode->pan[W] = mode->dim[W];
+ if (mode->pan[H] < mode->viewPortIn[H]) {
+ mode->pan[H] = mode->viewPortIn[H];
}
return mode;
@@ -669,8 +812,8 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic)
/* Panning domain */
- if (!be_generic || (mode->pan[W] != mode->dim[W] ||
- mode->pan[H] != mode->dim[H])) {
+ if (!be_generic || (mode->pan[W] != mode->viewPortIn[W] ||
+ mode->pan[H] != mode->viewPortIn[H])) {
tmp = g_strdup_printf("%s @%dx%d",
mode_str, mode->pan[W], mode->pan[H]);
g_free(mode_str);
@@ -685,10 +828,10 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic)
* the metamodes are generated:
*
* Programability:
- * make mode->dim relative to screen->dim
+ * make mode->viewPortIn relative to screen->dim
*
* Coherency:
- * make mode->dim relative to mode->metamode->edim
+ * make mode->viewPortIn relative to mode->metamode->edim
*
*
* XXX Also, we may want to take in consideration the
@@ -699,8 +842,8 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic)
tmp = g_strdup_printf("%s +%d+%d",
mode_str,
/* Make mode position relative */
- mode->dim[X] - mode->metamode->edim[X],
- mode->dim[Y] - mode->metamode->edim[Y]);
+ mode->viewPortIn[X] - mode->metamode->edim[X],
+ mode->viewPortIn[Y] - mode->metamode->edim[Y]);
g_free(mode_str);
mode_str = tmp;
@@ -709,29 +852,125 @@ static gchar *mode_get_str(nvModePtr mode, int be_generic)
flags_str = NULL;
/* Passive Stereo Eye */
- if (screen->stereo_supported && screen->stereo == 4) {
- const char *eye;
+ if (screen->stereo_supported &&
+ (screen->stereo == NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY)) {
+ const char *str = NULL;
switch (mode->passive_stereo_eye) {
case PASSIVE_STEREO_EYE_LEFT:
- eye = "PassiveLeft";
+ str = "PassiveLeft";
break;
case PASSIVE_STEREO_EYE_RIGHT:
- eye = "PassiveRight";
+ str = "PassiveRight";
break;
case 0:
default:
- eye = NULL;
+ str = NULL;
+ break;
+ }
+
+ if (str) {
+ tmp = g_strdup_printf("%s, stereo=%s", (flags_str ? flags_str : ""),
+ str);
+ g_free(flags_str);
+ flags_str = tmp;
+ }
+ }
+
+ /* Rotation */
+ if (mode->rotation != ROTATION_0) {
+ const char *str = NULL;
+
+ switch (mode->rotation) {
+ case ROTATION_90:
+ str = "90";
+ break;
+ case ROTATION_180:
+ str = "180";
+ break;
+ case ROTATION_270:
+ str = "270";
+ break;
+ default:
+ break;
+ }
+
+ if (str) {
+ tmp = g_strdup_printf("%s, rotation=%s",
+ (flags_str ? flags_str : ""), str);
+ g_free(flags_str);
+ flags_str = tmp;
+ }
+ }
+
+ /* Reflection */
+ if (mode->reflection != REFLECTION_NONE) {
+ const char *str = NULL;
+
+ switch (mode->reflection) {
+ case REFLECTION_X:
+ str = "X";
+ break;
+ case REFLECTION_Y:
+ str = "Y";
+ break;
+ case REFLECTION_XY:
+ str = "XY";
+ break;
+ default:
break;
}
- if (eye) {
- tmp = g_strdup_printf("%s, stereo=%s", (flags_str ? flags_str : ""), eye);
+ if (str) {
+ tmp = g_strdup_printf("%s, reflection=%s",
+ (flags_str ? flags_str : ""), str);
g_free(flags_str);
flags_str = tmp;
}
}
+ /* ViewPort in */
+ {
+ int width;
+ int height;
+
+ /* Only write out the ViewPortIn if it is specified and differes from
+ * the viewport out.
+ */
+ if ((mode->rotation == ROTATION_90) ||
+ (mode->rotation == ROTATION_270)) {
+ width = mode->viewPortOut[H];
+ height = mode->viewPortOut[W];
+ } else {
+ width = mode->viewPortOut[W];
+ height = mode->viewPortOut[H];
+ }
+
+ if (mode->viewPortIn[W] && mode->viewPortIn[H] &&
+ ((mode->viewPortIn[W] != width) ||
+ (mode->viewPortIn[H] != height))) {
+ tmp = g_strdup_printf("%s, viewportin=%dx%d",
+ (flags_str ? flags_str : ""),
+ mode->viewPortIn[W], mode->viewPortIn[H]);
+ g_free(flags_str);
+ flags_str = tmp;
+ }
+ }
+
+ /* ViewPort out */
+ if (mode->viewPortOut[X] ||
+ mode->viewPortOut[Y] ||
+ (mode->viewPortOut[W] && mode->viewPortOut[H] &&
+ ((mode->viewPortOut[W] != mode->modeline->data.hdisplay) ||
+ (mode->viewPortOut[H] != mode->modeline->data.vdisplay)))) {
+ tmp = g_strdup_printf("%s, viewportout=%dx%d%+d%+d",
+ (flags_str ? flags_str : ""),
+ mode->viewPortOut[W], mode->viewPortOut[H],
+ mode->viewPortOut[X], mode->viewPortOut[Y]);
+ g_free(flags_str);
+ flags_str = tmp;
+ }
+
if (flags_str) {
tmp = g_strdup_printf("%s {%s}",
mode_str,
@@ -837,6 +1076,9 @@ int display_find_closest_mode_matching_modeline(nvDisplayPtr display,
mode_idx = 0;
for (mode = display->modes; mode; mode = mode->next) {
+ if (!mode->modeline) {
+ continue;
+ }
if (mode->modeline->data.vdisplay == modeline->data.vdisplay &&
mode->modeline->data.hdisplay == modeline->data.hdisplay) {
match_idx = mode_idx;
@@ -1105,6 +1347,31 @@ void display_remove_modes(nvDisplayPtr display)
+/*!
+ * Sets all the modes on the display to the specified rotation
+ *
+ * \param[in] mode The display who's modes are to be modified
+ * \param[in] rotation The rotation to set
+ *
+ * \return TRUE if a new rotation was set for at least one mode, FALSE if all
+ * of the modes on the display were already set to the rotation given.
+ */
+Bool display_set_modes_rotation(nvDisplayPtr display, Rotation rotation)
+{
+ nvModePtr mode;
+ Bool modified = FALSE;
+
+ for (mode = display->modes; mode; mode = mode->next) {
+ if (mode_set_rotation(mode, rotation)) {
+ modified = TRUE;
+ }
+ }
+
+ return modified;
+}
+
+
+
/** display_free() ***************************************************
*
* Frees memory used by a display
@@ -1291,6 +1558,45 @@ void screen_unlink_display(nvDisplayPtr display)
} /* screen_unlink_display() */
+static void screen_link_displays(nvScreenPtr screen)
+{
+ ReturnStatus ret;
+ int *pData;
+ int len;
+ int i;
+
+ ret = NvCtrlGetBinaryAttribute
+ (screen->handle, 0, NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN,
+ (unsigned char **)(&pData), &len);
+
+ if (ret != NvCtrlSuccess) {
+ nv_warning_msg("Failed to query list of displays assigned to X screen "
+ " %d.",
+ NvCtrlGetTargetId(screen->handle));
+ return;
+ }
+
+ // For each id in pData
+ for (i = 0; i < pData[0]; i++) {
+ nvDisplayPtr display;
+
+ display = layout_get_display(screen->layout, pData[i+1]);
+ if (!display) {
+ nv_warning_msg("Failed to find display %d assigned to X screen "
+ " %d.",
+ pData[i+1],
+ NvCtrlGetTargetId(screen->handle));
+ continue;
+ }
+
+ screen_link_display(screen, display);
+ }
+
+ XFree(pData);
+}
+
+
+
/** screen_remove_display() ******************************************
*
@@ -1566,15 +1872,18 @@ static Bool screen_add_metamode(nvScreenPtr screen, const char *metamode_str,
/* Make the mode part of the metamode */
mode->metamode = metamode;
- /* Make the display part of the screen, and make sure it has the
- * right number of modes.
- */
+ /* On older X driver NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN
+ * attribute is Not Available so we are unable to link displays to
+ * the screen implicitly.
+ * To avoid display->cur_mode = NULL link displays explicitly.
+ */
screen_link_display(screen, display);
+ /* Make sure each display has the right number of (NULL) modes */
screen_check_metamodes(screen);
/* Set the panning offset */
- mode->pan[X] = mode->dim[X];
- mode->pan[Y] = mode->dim[Y];
+ mode->pan[X] = mode->viewPortIn[X];
+ mode->pan[Y] = mode->viewPortIn[Y];
/* Add the mode at the end of the display's mode list */
xconfigAddListItem((GenericListPtr *)(&display->modes),
@@ -1658,8 +1967,8 @@ static Bool screen_check_metamodes(nvScreenPtr screen)
/* Duplicate position information of the last mode */
if (last_mode) {
- mode->dim[X] = last_mode->dim[X];
- mode->dim[Y] = last_mode->dim[Y];
+ mode->viewPortIn[X] = last_mode->viewPortIn[X];
+ mode->viewPortIn[Y] = last_mode->viewPortIn[Y];
mode->pan[X] = last_mode->pan[X];
mode->pan[Y] = last_mode->pan[Y];
mode->position_type = last_mode->position_type;
@@ -1711,10 +2020,11 @@ static void screen_assign_dummy_metamode_positions(nvScreenPtr screen)
if (ok_mode) {
for (mode = display->modes; mode; mode = mode->next) {
if (!mode->dummy) continue;
- mode->dim[X] = ok_mode->dim[X];
- mode->pan[X] = ok_mode->dim[X];
- mode->dim[Y] = ok_mode->dim[Y];
- mode->pan[Y] = ok_mode->dim[Y];
+ mode->viewPortIn[X] = ok_mode->viewPortIn[X];
+ mode->viewPortIn[Y] = ok_mode->viewPortIn[Y];
+
+ mode->pan[X] = ok_mode->viewPortIn[X];
+ mode->pan[Y] = ok_mode->viewPortIn[Y];
}
}
}
@@ -2311,10 +2621,7 @@ Bool gpu_add_screenless_modes_to_displays(nvGpuPtr gpu)
mode->display = display;
mode->dummy = 1;
- mode->dim[W] = 800;
- mode->dim[H] = 600;
- mode->pan[W] = mode->dim[W];
- mode->pan[H] = mode->dim[H];
+ mode_set_dims_from_modeline(mode, NULL);
/* Add the mode to the display */
display->modes = mode;
@@ -2748,6 +3055,13 @@ static Bool layout_add_screen_from_server(nvLayoutPtr layout,
if (ret == NvCtrlSuccess) {
screen->stereo_supported = TRUE;
screen->stereo = val;
+
+ /* XXX For now, if stereo is off, don't show configuration options
+ * until we work out interactions with composite.
+ */
+ if (val == NV_CTRL_STEREO_OFF) {
+ screen->stereo_supported = FALSE;
+ }
} else {
screen->stereo_supported = FALSE;
}
@@ -2818,6 +3132,9 @@ static Bool layout_add_screen_from_server(nvLayoutPtr layout,
/* Add the screen to the layout */
layout_add_screen(layout, screen);
+ /* Link displays to the screen */
+ screen_link_displays(screen);
+
/* Parse the screen's metamodes (ties displays on the gpu to the screen) */
if (!screen->no_scanout) {
if (!screen_add_metamodes(screen, err_str)) {
diff --git a/src/gtk+-2.x/ctkdisplayconfig-utils.h b/src/gtk+-2.x/ctkdisplayconfig-utils.h
index 5aeb84f..14252aa 100644
--- a/src/gtk+-2.x/ctkdisplayconfig-utils.h
+++ b/src/gtk+-2.x/ctkdisplayconfig-utils.h
@@ -48,6 +48,8 @@ void apply_screen_info_token(char *token, char *value, void *data);
/* Mode functions */
+void mode_set_dims_from_modeline(nvModePtr mode, nvModeLinePtr modeline);
+Bool mode_set_rotation(nvModePtr mode, Rotation rotation);
nvModePtr mode_parse(nvDisplayPtr display, const char *mode_str);
/* ModeLine functions */
@@ -65,6 +67,7 @@ Bool display_has_modeline(nvDisplayPtr display, nvModeLinePtr modeline);
Bool display_add_modelines_from_server(nvDisplayPtr display, nvGpuPtr gpu,
gchar **err_str);
void display_remove_modes(nvDisplayPtr display);
+Bool display_set_modes_rotation(nvDisplayPtr display, Rotation rotation);
/* Metamode functions */
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 794bec2..4b5caed 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -61,20 +61,23 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data);
static void display_refresh_changed(GtkWidget *widget, gpointer user_data);
static void display_stereo_changed(GtkWidget *widget, gpointer user_data);
+static void display_rotation_changed(GtkWidget *widget, gpointer user_data);
+static void display_reflection_changed(GtkWidget *widget, gpointer user_data);
static void display_position_type_changed(GtkWidget *widget, gpointer user_data);
static void display_position_offset_activate(GtkWidget *widget, gpointer user_data);
static void display_position_relative_changed(GtkWidget *widget, gpointer user_data);
-static void display_panning_activate(GtkWidget *widget, gpointer user_data);
-static gboolean display_panning_focus_out(GtkWidget *widget, GdkEvent *event,
+static void display_viewport_in_activate(GtkWidget *widget, gpointer user_data);
+static void display_viewport_out_activate(GtkWidget *widget,
gpointer user_data);
+static void display_panning_activate(GtkWidget *widget, gpointer user_data);
static void setup_screen_page(CtkDisplayConfig *ctk_object);
static void screen_virtual_size_activate(GtkWidget *widget, gpointer user_data);
-static gboolean screen_virtual_size_focus_out(GtkWidget *widget, GdkEvent *event,
- gpointer user_data);
+static gboolean txt_focus_out(GtkWidget *widget, GdkEvent *event,
+ gpointer user_data);
static void screen_depth_changed(GtkWidget *widget, gpointer user_data);
@@ -188,7 +191,24 @@ static const char * __dpy_refresh_mnu_help =
static const char * __dpy_stereo_help =
"The Display Passive Stereo Eye drop-down allows you to select a desired "
"stereo eye the display should output when Passive Stereo (Mode 4) is "
-"selected enabled.";
+"enabled.";
+
+static const char * __dpy_rotation_help =
+"The Display Rotation drop-down allows you to select the desired orientation "
+"for the display.";
+
+static const char * __dpy_reflection_help =
+"The Display Reflection drop-down allows you to choose the axes across which "
+"monitor contents should be reflected.";
+
+static const char * __dpy_viewport_in_help =
+"This defines the width and height in pixels of the region that should be "
+"displayed from the desktop.";
+
+static const char * __dpy_viewport_out_help =
+"This defines the width, height, and offset of the output region in raster "
+"space, into which the ViewPortIn is to be displayed (along with any "
+"transform, such as rotation, reflection, etc.)";
static const char * __dpy_position_type_help =
"The Position Type drop-down allows you to set how the selected display "
@@ -1385,6 +1405,44 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
"changed", G_CALLBACK(display_stereo_changed),
(gpointer) ctk_object);
+ /* Display rotation dropdown */
+ ctk_object->mnu_display_rotation = gtk_option_menu_new();
+ menu = gtk_menu_new();
+ menu_item = gtk_menu_item_new_with_label("No Rotation");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ menu_item = gtk_menu_item_new_with_label("Rotate 90");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ menu_item = gtk_menu_item_new_with_label("Rotate 180");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ menu_item = gtk_menu_item_new_with_label("Rotate 270");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_option_menu_set_menu
+ (GTK_OPTION_MENU(ctk_object->mnu_display_rotation), menu);
+ ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_rotation,
+ __dpy_rotation_help);
+ g_signal_connect(G_OBJECT(ctk_object->mnu_display_rotation),
+ "changed", G_CALLBACK(display_rotation_changed),
+ (gpointer) ctk_object);
+
+ /* Display reflection dropdown */
+ ctk_object->mnu_display_reflection = gtk_option_menu_new();
+ menu = gtk_menu_new();
+ menu_item = gtk_menu_item_new_with_label("No Reflection");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ menu_item = gtk_menu_item_new_with_label("Reflect along X");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ menu_item = gtk_menu_item_new_with_label("Reflect along Y");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ menu_item = gtk_menu_item_new_with_label("Reflect along XY");
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+ gtk_option_menu_set_menu
+ (GTK_OPTION_MENU(ctk_object->mnu_display_reflection), menu);
+ ctk_config_set_tooltip(ctk_config, ctk_object->mnu_display_reflection,
+ __dpy_reflection_help);
+ g_signal_connect(G_OBJECT(ctk_object->mnu_display_reflection),
+ "changed", G_CALLBACK(display_reflection_changed),
+ (gpointer) ctk_object);
+
/* Display Position Type (Absolute/Relative Menu) */
ctk_object->mnu_display_position_type = gtk_option_menu_new();
menu = gtk_menu_new();
@@ -1426,6 +1484,28 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
"activate", G_CALLBACK(display_position_offset_activate),
(gpointer) ctk_object);
+ /* Display ViewPort In */
+ ctk_object->txt_display_viewport_in = gtk_entry_new();
+ ctk_config_set_tooltip(ctk_config, ctk_object->txt_display_viewport_in,
+ __dpy_viewport_in_help);
+ g_signal_connect(G_OBJECT(ctk_object->txt_display_viewport_in), "activate",
+ G_CALLBACK(display_viewport_in_activate),
+ (gpointer) ctk_object);
+ g_signal_connect(G_OBJECT(ctk_object->txt_display_viewport_in), "focus-out-event",
+ G_CALLBACK(txt_focus_out),
+ (gpointer) ctk_object);
+
+ /* Display ViewPort Out */
+ ctk_object->txt_display_viewport_out = gtk_entry_new();
+ ctk_config_set_tooltip(ctk_config, ctk_object->txt_display_viewport_out,
+ __dpy_viewport_out_help);
+ g_signal_connect(G_OBJECT(ctk_object->txt_display_viewport_out), "activate",
+ G_CALLBACK(display_viewport_out_activate),
+ (gpointer) ctk_object);
+ g_signal_connect(G_OBJECT(ctk_object->txt_display_viewport_out), "focus-out-event",
+ G_CALLBACK(txt_focus_out),
+ (gpointer) ctk_object);
+
/* Display Panning */
ctk_object->txt_display_panning = gtk_entry_new();
ctk_config_set_tooltip(ctk_config, ctk_object->txt_display_panning,
@@ -1434,7 +1514,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
G_CALLBACK(display_panning_activate),
(gpointer) ctk_object);
g_signal_connect(G_OBJECT(ctk_object->txt_display_panning), "focus-out-event",
- G_CALLBACK(display_panning_focus_out),
+ G_CALLBACK(txt_focus_out),
(gpointer) ctk_object);
/* X screen virtual size */
@@ -1446,7 +1526,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
(gpointer) ctk_object);
g_signal_connect(G_OBJECT(ctk_object->txt_screen_virtual_size),
"focus-out-event",
- G_CALLBACK(screen_virtual_size_focus_out),
+ G_CALLBACK(txt_focus_out),
(gpointer) ctk_object);
/* X screen depth */
@@ -1698,6 +1778,18 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(ctk_object), vbox, FALSE, FALSE, 0);
ctk_object->display_page = vbox;
+ /* Info on how to drag X screens around */
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5);
+
+ label = gtk_label_new("");
+ labels = g_slist_append(labels, label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+
+ label = gtk_label_new("(CTRL-Click + Drag to move X screens)");
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+ ctk_object->box_screen_drag_info_display = hbox;
+
/* Display Configuration */
label = gtk_label_new("Configuration:");
labels = g_slist_append(labels, label);
@@ -1733,11 +1825,6 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
FALSE, FALSE, 0);
ctk_object->box_display_modename = hbox;
- /*
- * XXX Disabled until we have support for identifying and handling
- * Stereo vs Composite incompatibility.
- */
- #if 0
/* Display passive stereo eye dropdown */
label = gtk_label_new("Stereo Eye:");
labels = g_slist_append(labels, label);
@@ -1748,9 +1835,28 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_display_stereo,
TRUE, TRUE, 0);
ctk_object->box_display_stereo = hbox;
- #else
- ctk_object->box_display_stereo = NULL;
- #endif
+
+ /* Display rotation & reflection dropdowns */
+ {
+ GtkWidget *hbox2 = gtk_hbox_new(TRUE, 0);
+
+ label = gtk_label_new("Orientation:");
+ labels = g_slist_append(labels, label);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox2), hbox, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_display_rotation,
+ TRUE, TRUE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_end(GTK_BOX(hbox2), hbox, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_display_reflection,
+ TRUE, TRUE, 0);
+
+ gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, TRUE, 0);
+ ctk_object->box_display_orientation = hbox2;
+ }
/* Display positioning */
label = gtk_label_new("Position:");
@@ -1770,6 +1876,30 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
TRUE, TRUE, 0);
ctk_object->box_display_position = hbox;
+ /* Display ViewPort In */
+ label = gtk_label_new("ViewPort In:");
+ labels = g_slist_append(labels, label);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_object->txt_display_viewport_in,
+ TRUE, TRUE, 0);
+ ctk_object->box_display_viewport_in = hbox;
+
+ /* Display ViewPort Out */
+ label = gtk_label_new("ViewPort Out:");
+ labels = g_slist_append(labels, label);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_object->txt_display_viewport_out,
+ TRUE, TRUE, 0);
+ ctk_object->box_display_viewport_out = hbox;
+
/* Display panning text entry */
label = gtk_label_new("Panning:");
labels = g_slist_append(labels, label);
@@ -1819,7 +1949,7 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
label = gtk_label_new("(CTRL-Click + Drag to move X screens)");
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 5);
- ctk_object->box_screen_drag_info = hbox;
+ ctk_object->box_screen_drag_info_screen = hbox;
/* X screen virtual size */
label = gtk_label_new("Virtual Size:");
@@ -1843,11 +1973,6 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
TRUE, TRUE, 0);
ctk_object->box_screen_depth = hbox;
- /*
- * XXX Disabled until we have support for identifying and handling
- * Stereo vs Composite incompatibility.
- */
- #if 0
/* X screen stereo dropdown */
label = gtk_label_new("Stereo Mode:");
labels = g_slist_append(labels, label);
@@ -1858,9 +1983,6 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(hbox), ctk_object->mnu_screen_stereo,
TRUE, TRUE, 0);
ctk_object->box_screen_stereo = hbox;
- #else
- ctk_object->box_screen_stereo = NULL;
- #endif
/* X screen positioning */
label = gtk_label_new("Position:");
@@ -2007,9 +2129,9 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
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, "Display Configuration Help");
@@ -2051,12 +2173,23 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, "The Mode name is the name of the modeline that is "
"currently chosen for the selected display device. "
"This is only available when advanced view is enabled.");
+ ctk_help_heading(b, &i, "Stereo Eye");
+ ctk_help_para(b, &i, __dpy_stereo_help);
+ ctk_help_heading(b, &i, "Orientation");
+ ctk_help_para(b, &i, "The Orientation drop-downs control how the desktop "
+ "image is rotated and/or reflected. %s %s Note that "
+ "reflection is applied before rotation.",
+ __dpy_rotation_help, __dpy_reflection_help);
ctk_help_heading(b, &i, "Position Type");
ctk_help_para(b, &i, __dpy_position_type_help);
ctk_help_heading(b, &i, "Position Relative");
ctk_help_para(b, &i, __dpy_position_relative_help);
ctk_help_heading(b, &i, "Position Offset");
ctk_help_para(b, &i, __dpy_position_offset_help);
+ ctk_help_heading(b, &i, "ViewPort In");
+ ctk_help_para(b, &i, __dpy_viewport_in_help);
+ ctk_help_heading(b, &i, "ViewPort Out");
+ ctk_help_para(b, &i, __dpy_viewport_out_help);
ctk_help_heading(b, &i, "Panning");
ctk_help_para(b, &i, "%s This is only available when advanced "
"view is enabled.", __dpy_panning_help);
@@ -2075,6 +2208,8 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
__screen_virtual_size_help);
ctk_help_heading(b, &i, "Color Depth");
ctk_help_para(b, &i, __screen_depth_help);
+ ctk_help_heading(b, &i, "Stereo Mode");
+ ctk_help_para(b, &i, __screen_stereo_help);
ctk_help_heading(b, &i, "Position Type");
ctk_help_para(b, &i, __screen_position_type_help);
ctk_help_heading(b, &i, "Position Relative");
@@ -2090,8 +2225,8 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
ctk_help_heading(b, &i, "Delete Metamode");
ctk_help_para(b, &i, "%s This is only available when advanced view "
"is enabled.", __screen_metamode_delete_button_help);
-
-
+
+
ctk_help_para(b, &i, "");
ctk_help_heading(b, &i, "Buttons");
ctk_help_heading(b, &i, "Apply");
@@ -2329,6 +2464,7 @@ static void setup_selected_item_dropdown(CtkDisplayConfig *ctk_object)
}
gtk_widget_set_sensitive(ctk_object->mnu_selected_item, True);
+ gtk_widget_show(ctk_object->mnu_selected_item);
menu = generate_selected_item_dropdown(ctk_object, display, screen,
&cur_idx);
@@ -2404,8 +2540,6 @@ static void setup_display_config(CtkDisplayConfig *ctk_object)
nvScreenPtr screen = NULL;
int num_screens_on_gpu = 0;
- if (!display) return;
-
/* Don't allow disabling the last display device */
if (ctk_object->layout->num_screens == 1 &&
display->screen &&
@@ -2724,7 +2858,7 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
/* Get selection information */
- if (!display || !display->screen || !display->cur_mode) {
+ if (!display->screen || !display->cur_mode) {
gtk_widget_hide(ctk_object->box_display_resolution);
return;
}
@@ -2865,8 +2999,8 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
/** setup_display_stereo_dropdown() **********************************
*
- * Configures the screen stereo mode dropdown to reflect the
- * stereo mode for the currently selected screen.
+ * Configures the display stereo mode dropdown to reflect the
+ * stereo eye for the currently selected display.
*
**/
@@ -2879,10 +3013,9 @@ static void setup_display_stereo_dropdown(CtkDisplayConfig *ctk_object)
nvModePtr mode;
int idx;
- if (!ctk_object->box_display_stereo) return;
-
- if (!display || !display->cur_mode || !screen ||
- !screen->stereo_supported || (screen->stereo != 4)) {
+ if (!display->cur_mode || !screen ||
+ !screen->stereo_supported ||
+ (screen->stereo != NV_CTRL_STEREO_PASSIVE_EYE_PER_DPY)) {
gtk_widget_hide(ctk_object->box_display_stereo);
return;
}
@@ -2922,6 +3055,209 @@ static void setup_display_stereo_dropdown(CtkDisplayConfig *ctk_object)
+/** setup_display_rotation_dropdown() ********************************
+ *
+ * Configures the display rotation dropdown to reflect the current
+ * rotation configuration.
+ *
+ **/
+
+static void setup_display_rotation_dropdown(CtkDisplayConfig *ctk_object)
+{
+ nvDisplayPtr display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+ int idx;
+
+ if (!display->screen) {
+ gtk_widget_hide(ctk_object->box_display_orientation);
+ return;
+ }
+ gtk_widget_show(ctk_object->box_display_orientation);
+
+ if (!display->cur_mode || !display->cur_mode->modeline) {
+ gtk_widget_set_sensitive(ctk_object->box_display_orientation, FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive(ctk_object->box_display_orientation, TRUE);
+
+ /* Set the selected rotation */
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_object->mnu_display_rotation),
+ G_CALLBACK(display_rotation_changed), (gpointer) ctk_object);
+
+ switch (display->cur_mode->rotation) {
+ default:
+ /* Oops */
+ case ROTATION_0:
+ idx = 0;
+ break;
+ case ROTATION_90:
+ idx = 1;
+ break;
+ case ROTATION_180:
+ idx = 2;
+ break;
+ case ROTATION_270:
+ idx = 3;
+ break;
+ }
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_object->mnu_display_rotation), idx);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_object->mnu_display_rotation),
+ G_CALLBACK(display_rotation_changed), (gpointer) ctk_object);
+
+} /* setup_display_rotation_dropdown() */
+
+
+
+/** setup_display_reflection_dropdown() ******************************
+ *
+ * Configures the display reflection dropdown to reflect the current
+ * reflection configuration.
+ *
+ **/
+
+static void setup_display_reflection_dropdown(CtkDisplayConfig *ctk_object)
+{
+ nvDisplayPtr display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+ int idx;
+
+ if (!display->screen) {
+ gtk_widget_hide(ctk_object->box_display_orientation);
+ return;
+ }
+ gtk_widget_show(ctk_object->box_display_orientation);
+
+ if (!display->cur_mode || !display->cur_mode->modeline) {
+ gtk_widget_set_sensitive(ctk_object->box_display_orientation, FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive(ctk_object->box_display_orientation, TRUE);
+
+ /* Set the selected reflection */
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_object->mnu_display_reflection),
+ G_CALLBACK(display_reflection_changed), (gpointer) ctk_object);
+
+ switch (display->cur_mode->reflection) {
+ default:
+ /* Oops */
+ case REFLECTION_NONE:
+ idx = 0;
+ break;
+ case REFLECTION_X:
+ idx = 1;
+ break;
+ case REFLECTION_Y:
+ idx = 2;
+ break;
+ case REFLECTION_XY:
+ idx = 3;
+ break;
+ }
+
+ gtk_option_menu_set_history
+ (GTK_OPTION_MENU(ctk_object->mnu_display_reflection), idx);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_object->mnu_display_reflection),
+ G_CALLBACK(display_reflection_changed), (gpointer) ctk_object);
+
+} /* setup_display_reflection_dropdown() */
+
+
+
+/** setup_display_viewport_in() **************************************
+ *
+ * Sets up the display viewport in text entry to reflect the currently
+ * selected display device/mode.
+ *
+ **/
+
+static void setup_display_viewport_in(CtkDisplayConfig *ctk_object)
+{
+ char *tmp_str;
+ nvDisplayPtr display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+ nvModePtr mode;
+
+ if (!display || !display->screen || !ctk_object->advanced_mode) {
+ gtk_widget_hide(ctk_object->box_display_viewport_in);
+ return;
+ }
+ gtk_widget_show(ctk_object->box_display_viewport_in);
+
+ if (!display->cur_mode || !display->cur_mode->modeline) {
+ gtk_widget_set_sensitive(ctk_object->box_display_viewport_in, FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive(ctk_object->box_display_viewport_in, TRUE);
+
+ /* Update the text */
+ mode = display->cur_mode;
+
+ tmp_str = g_strdup_printf("%dx%d",
+ mode->viewPortIn[W],
+ mode->viewPortIn[H]);
+
+ gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_viewport_in),
+ tmp_str);
+
+ g_free(tmp_str);
+
+} /* setup_display_viewport_in() */
+
+
+
+/** setup_display_viewport_out() *************************************
+ *
+ * Sets up the display viewport out text entry to reflect the currently
+ * selected display device/mode.
+ *
+ **/
+
+static void setup_display_viewport_out(CtkDisplayConfig *ctk_object)
+{
+ char *tmp_str;
+ nvDisplayPtr display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+ nvModePtr mode;
+
+ if (!display || !display->screen || !ctk_object->advanced_mode) {
+ gtk_widget_hide(ctk_object->box_display_viewport_out);
+ return;
+ }
+ gtk_widget_show(ctk_object->box_display_viewport_out);
+
+ if (!display->cur_mode || !display->cur_mode->modeline) {
+ gtk_widget_set_sensitive(ctk_object->box_display_viewport_out, FALSE);
+ return;
+ }
+ gtk_widget_set_sensitive(ctk_object->box_display_viewport_out, TRUE);
+
+
+ /* Update the text */
+ mode = display->cur_mode;
+
+ tmp_str = g_strdup_printf("%dx%d%+d%+d",
+ mode->viewPortOut[W],
+ mode->viewPortOut[H],
+ mode->viewPortOut[X],
+ mode->viewPortOut[Y]);
+
+ gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_viewport_out),
+ tmp_str);
+
+ g_free(tmp_str);
+
+} /* setup_display_viewport_out() */
+
+
+
/** setup_display_position_type() ************************************
*
* Sets up the display position type dropdown to reflect the position
@@ -3101,8 +3437,8 @@ static void setup_display_position_offset(CtkDisplayConfig *ctk_object)
mode = display->cur_mode;
tmp_str = g_strdup_printf("%+d%+d",
- mode->dim[X] - mode->metamode->edim[X],
- mode->dim[Y] - mode->metamode->edim[Y]);
+ mode->viewPortIn[X] - mode->metamode->edim[X],
+ mode->viewPortIn[Y] - mode->metamode->edim[Y]);
gtk_entry_set_text(GTK_ENTRY(ctk_object->txt_display_position_offset),
tmp_str);
@@ -3164,13 +3500,13 @@ static void setup_primary_display(CtkDisplayConfig *ctk_object)
{
nvDisplayPtr display = ctk_display_layout_get_selected_display
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
-
+
/* Hide the checkbox if this screen only has one display */
- if (!display || !display->screen || display->screen->num_displays <= 1) {
+ if (!display->screen || display->screen->num_displays <= 1) {
gtk_widget_hide(ctk_object->chk_primary_display);
return;
}
-
+
gtk_widget_show(ctk_object->chk_primary_display);
g_signal_handlers_block_by_func
@@ -3263,10 +3599,20 @@ static void setup_display_page(CtkDisplayConfig *ctk_object)
/* Enable display widgets and setup widget information */
gtk_widget_set_sensitive(ctk_object->display_page, True);
+ if (display->gpu->layout->num_screens > 1) {
+ gtk_widget_show(ctk_object->box_screen_drag_info_display);
+ } else {
+ gtk_widget_hide(ctk_object->box_screen_drag_info_display);
+ }
+
setup_display_config(ctk_object);
setup_display_modename(ctk_object);
setup_display_resolution_dropdown(ctk_object);
setup_display_stereo_dropdown(ctk_object);
+ setup_display_rotation_dropdown(ctk_object);
+ setup_display_reflection_dropdown(ctk_object);
+ setup_display_viewport_in(ctk_object);
+ setup_display_viewport_out(ctk_object);
setup_display_position(ctk_object);
setup_display_panning(ctk_object);
setup_primary_display(ctk_object);
@@ -3761,9 +4107,9 @@ static void setup_screen_page(CtkDisplayConfig *ctk_object)
gtk_widget_set_sensitive(ctk_object->screen_page, True);
if (screen->layout->num_screens > 1) {
- gtk_widget_show(ctk_object->box_screen_drag_info);
+ gtk_widget_show(ctk_object->box_screen_drag_info_screen);
} else {
- gtk_widget_hide(ctk_object->box_screen_drag_info);
+ gtk_widget_hide(ctk_object->box_screen_drag_info_screen);
}
setup_screen_virtual_size(ctk_object);
@@ -4239,17 +4585,12 @@ void layout_modified_callback(nvLayoutPtr layout, void *data)
/* Sync the information displayed by the GUI to match the settings
* of the currently selected display device.
*/
-
- /* Setup position */
+ setup_display_viewport_in(ctk_object);
+ setup_display_viewport_out(ctk_object);
setup_display_position(ctk_object);
-
-
- /* Setup panning */
setup_display_panning(ctk_object);
setup_screen_position(ctk_object);
-
- /* Setup screen virtual size */
setup_screen_virtual_size(ctk_object);
/* If the positioning of the X screen changes, we cannot apply */
@@ -4335,10 +4676,8 @@ static void do_enable_display_for_xscreen(CtkDisplayConfig *ctk_object,
mode->metamode = metamode;
/* XXX Hopefully display->modelines is 'nvidia-auto-select' */
- mode->dim[W] = display->modelines->data.hdisplay;
- mode->dim[H] = display->modelines->data.vdisplay;
- mode->pan[W] = mode->dim[W];
- mode->pan[H] = mode->dim[H];
+ mode_set_dims_from_modeline(mode, display->modelines);
+
mode->position_type = CONF_ADJ_ABSOLUTE;
@@ -4373,14 +4712,14 @@ static void do_enable_display_for_xscreen(CtkDisplayConfig *ctk_object,
if (rightmost) {
screen->position_type = CONF_ADJ_RIGHTOF;
screen->relative_to = rightmost;
- screen->dim[X] = mode->dim[X] = rightmost->dim[X];
- screen->dim[Y] = mode->dim[Y] = rightmost->dim[Y];
+ screen->dim[X] = mode->viewPortIn[X] = rightmost->dim[X];
+ screen->dim[Y] = mode->viewPortIn[Y] = rightmost->dim[Y];
} else {
screen->position_type = CONF_ADJ_ABSOLUTE;
screen->relative_to = NULL;
- screen->dim[X] = mode->dim[X];
- screen->dim[Y] = mode->dim[Y];
+ screen->dim[X] = mode->viewPortIn[X];
+ screen->dim[Y] = mode->viewPortIn[Y];
}
@@ -4529,8 +4868,8 @@ static void do_enable_display_for_twinview(CtkDisplayConfig *ctk_object,
for (other = screen->displays; other; other = other->next_in_screen) {
for (mode = other->modes; mode; mode = mode->next) {
if (!rightmost ||
- ((mode->dim[X] + mode->dim[W]) >
- (rightmost->dim[X] + rightmost->dim[W]))) {
+ ((mode->viewPortIn[X] + mode->viewPortIn[W]) >
+ (rightmost->viewPortIn[X] + rightmost->viewPortIn[W]))) {
rightmost = mode;
}
}
@@ -4552,17 +4891,17 @@ static void do_enable_display_for_twinview(CtkDisplayConfig *ctk_object,
if (rightmost) {
mode->position_type = CONF_ADJ_RIGHTOF;
mode->relative_to = rightmost->display;
- mode->dim[X] = rightmost->display->cur_mode->dim[X];
- mode->dim[Y] = rightmost->display->cur_mode->dim[Y];
- mode->pan[X] = mode->dim[X];
- mode->pan[Y] = mode->dim[Y];
+ mode->viewPortIn[X] = rightmost->display->cur_mode->viewPortIn[X];
+ mode->viewPortIn[Y] = rightmost->display->cur_mode->viewPortIn[Y];
+ mode->pan[X] = mode->viewPortIn[X];
+ mode->pan[Y] = mode->viewPortIn[Y];
} else {
mode->position_type = CONF_ADJ_ABSOLUTE;
mode->relative_to = NULL;
- mode->dim[X] = metamode->dim[X] + metamode->dim[W];
- mode->dim[Y] = metamode->dim[Y];
- mode->pan[X] = mode->dim[X];
- mode->pan[Y] = mode->dim[Y];
+ mode->viewPortIn[X] = metamode->dim[X] + metamode->dim[W];
+ mode->viewPortIn[Y] = metamode->dim[Y];
+ mode->pan[X] = mode->viewPortIn[X];
+ mode->pan[Y] = mode->viewPortIn[Y];
}
@@ -4806,17 +5145,17 @@ static void do_configure_display_for_twinview(CtkDisplayConfig *ctk_object,
if (metamode == use_screen->cur_metamode) {
display->cur_mode = mode;
}
-
+
/* Duplicate position information of the last mode */
if (last_mode) {
- mode->dim[X] = last_mode->dim[X];
- mode->dim[Y] = last_mode->dim[Y];
+ mode->viewPortIn[X] = last_mode->viewPortIn[X];
+ mode->viewPortIn[Y] = last_mode->viewPortIn[Y];
mode->pan[X] = last_mode->pan[X];
mode->pan[Y] = last_mode->pan[Y];
mode->position_type = last_mode->position_type;
mode->relative_to = last_mode->relative_to;
}
-
+
/* Add the mode at the end of display's mode list */
xconfigAddListItem((GenericListPtr *)(&display->modes),
(GenericListPtr)mode);
@@ -5172,18 +5511,13 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data)
display->cur_mode, modeline);
- /* Regenerate the refresh menu */
+ /* Update the UI */
setup_display_refresh_dropdown(ctk_object);
-
-
- /* Sync the display position */
+ setup_display_viewport_in(ctk_object);
+ setup_display_viewport_out(ctk_object);
setup_display_position(ctk_object);
-
-
- /* Sync the panning domain */
setup_display_panning(ctk_object);
-
user_changed_attributes(ctk_object);
} /* display_resolution_changed() */
@@ -5225,10 +5559,107 @@ static void display_stereo_changed(GtkWidget *widget, gpointer user_data)
}
}
+ user_changed_attributes(ctk_object);
+
} /* display_stereo_changed() */
+/** display_rotation_changed() ***************************************
+ *
+ * Called when user selects a new rotation orientation.
+ *
+ **/
+static void display_rotation_changed(GtkWidget *widget, gpointer user_data)
+{
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
+ nvDisplayPtr display;
+ gint idx;
+ Rotation rotation;
+
+
+ /* Update the current mode on the selected display */
+ display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+
+ if (!display ||
+ !display->cur_mode ||
+ !display->cur_mode->modeline) {
+ return;
+ }
+
+ idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ switch (idx) {
+ case 1:
+ rotation = ROTATION_90;
+ break;
+ case 2:
+ rotation = ROTATION_180;
+ break;
+ case 3:
+ rotation = ROTATION_270;
+ break;
+ default:
+ case 0:
+ rotation = ROTATION_0;
+ break;
+ }
+
+ ctk_display_layout_set_display_rotation
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
+ display, rotation);
+
+} /* display_rotation_changed() */
+
+
+
+/** display_reflection_changed() *************************************
+ *
+ * Called when user selectes a new reflection axis.
+ *
+ **/
+static void display_reflection_changed(GtkWidget *widget, gpointer user_data)
+{
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
+ nvDisplayPtr display;
+ gint idx;
+ Reflection reflection;
+
+ /* Update the current mode on the selected display */
+ display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+
+ if (!display ||
+ !display->cur_mode ||
+ !display->cur_mode->modeline) {
+ return;
+ }
+
+ idx = gtk_option_menu_get_history(GTK_OPTION_MENU(widget));
+ switch (idx) {
+ case 1:
+ reflection = REFLECTION_X;
+ break;
+ case 2:
+ reflection = REFLECTION_Y;
+ break;
+ case 3:
+ reflection = REFLECTION_XY;
+ break;
+ default:
+ case 0:
+ reflection = REFLECTION_NONE;
+ break;
+ }
+
+ ctk_display_layout_set_display_reflection
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
+ display, reflection);
+
+} /* display_reflection_changed() */
+
+
+
/** display_position_type_changed() **********************************
*
* Called when user selects a new display position method (relative/
@@ -5266,13 +5697,13 @@ static void display_position_type_changed(GtkWidget *widget,
relative_to =
ctk_object->display_position_table[relative_to_idx];
-
+
/* Update the layout */
ctk_display_layout_set_display_position
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
display, position_type, relative_to,
- display->cur_mode->dim[X],
- display->cur_mode->dim[Y]);
+ display->cur_mode->viewPortIn[X],
+ display->cur_mode->viewPortIn[Y]);
}
@@ -5387,6 +5818,79 @@ static void display_position_offset_activate(GtkWidget *widget,
+/** display_viewport_in_activate() ***********************************
+ *
+ * Called when user modifies the display viewport in text entry.
+ *
+ **/
+
+static void display_viewport_in_activate(GtkWidget *widget, gpointer user_data)
+{
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
+ const gchar *str = gtk_entry_get_text(GTK_ENTRY(widget));
+ int w, h;
+ nvDisplayPtr display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+
+
+ if (!display || !display->cur_mode) {
+ return;
+ }
+
+ str = parse_read_integer_pair(str, 'x', &w, &h);
+ if (!str) {
+ /* Reset the mode's viewport in */
+ setup_display_viewport_in(ctk_object);
+ return;
+ }
+
+ ctk_display_layout_set_mode_viewport_in
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), display->cur_mode, w, h);
+
+} /* display_viewport_in_activate() */
+
+
+
+/** display_viewport_out_activate() **********************************
+ *
+ * Called when user modifies the display viewport out text entry.
+ *
+ **/
+
+static void display_viewport_out_activate(GtkWidget *widget, gpointer user_data)
+{
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
+ const gchar *str = gtk_entry_get_text(GTK_ENTRY(widget));
+ int w, h, x, y;
+ nvDisplayPtr display = ctk_display_layout_get_selected_display
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout));
+
+
+ if (!display || !display->cur_mode) {
+ return;
+ }
+
+ str = parse_read_integer_pair(str, 'x', &w, &h);
+ if (!str) {
+ /* Reset the mode's viewport out */
+ setup_display_viewport_out(ctk_object);
+ return;
+ }
+ str = parse_read_integer_pair(str, 0, &x, &y);
+ if (!str) {
+ /* Reset the mode's viewport out */
+ setup_display_viewport_out(ctk_object);
+ return;
+ }
+
+ ctk_display_layout_set_mode_viewport_out
+ (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), display->cur_mode,
+ x, y, w, h);
+
+} /* display_viewport_out_activate() */
+
+
+
/** display_panning_activate() ***************************************
*
* Called when user modifies the display position text entry.
@@ -5405,7 +5909,7 @@ static void display_panning_activate(GtkWidget *widget, gpointer user_data)
if (!display) {
return;
}
-
+
str = parse_read_integer_pair(str, 'x', &x, &y);
if (!str) {
/* Reset the display panning */
@@ -5420,23 +5924,6 @@ static void display_panning_activate(GtkWidget *widget, gpointer user_data)
-/** display_panning_focus_out() **************************************
- *
- * Called when user leaves the panning entry
- *
- **/
-
-static gboolean display_panning_focus_out(GtkWidget *widget, GdkEvent *event,
- gpointer user_data)
-{
- display_panning_activate(widget, user_data);
-
- return FALSE;
-
-} /* display_panning_focus_out() */
-
-
-
/** screen_virtual_size_activate() ***********************************
*
* Called when user modifies the screen virtual size text entry.
@@ -5472,21 +5959,30 @@ static void screen_virtual_size_activate(GtkWidget *widget, gpointer user_data)
-/** screen_virtual_size_focus_out() **********************************
+/** txt_focus_out() **************************************************
*
- * Called when user leaves the screen virtual size entry
+ * Called when user leaves a txt entry
*
**/
-static gboolean screen_virtual_size_focus_out(GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
+static gboolean txt_focus_out(GtkWidget *widget, GdkEvent *event,
+ gpointer user_data)
{
- screen_virtual_size_activate(widget, user_data);
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
+
+ if (widget == ctk_object->txt_display_viewport_in) {
+ display_viewport_in_activate(widget, user_data);
+ } else if (widget == ctk_object->txt_display_viewport_out) {
+ display_viewport_out_activate(widget, user_data);
+ } else if (widget == ctk_object->txt_display_panning) {
+ display_panning_activate(widget, user_data);
+ } else if (widget == ctk_object->txt_screen_virtual_size) {
+ screen_virtual_size_activate(widget, user_data);
+ }
return FALSE;
-} /* screen_virtual_size_focus_out() */
+} /* txt_focus_out() */
@@ -6128,39 +6624,30 @@ static Bool switch_to_current_metamode(CtkDisplayConfig *ctk_object,
-/** find_metamode_string() *******************************************
+/** find_metamode_string_by_id() *************************************
*
- * Finds "metamode_str" in the list of strings in metamode_strs.
- * If metamode_str is found, a pointer to the full metamode string
- * is returned (including tokens, if any.)
- *
- * if "metamode_str" is not found in "metamode_strs", NULL is
- * returned.
+ * Looks in the list of strings (metamode_strs) for a metamode with
+ * the given id (defined by string 'id_str') and returns the pointer
+ * to it, or NULL if not found.
*
**/
-static char *find_metamode_string(char *metamode_str, char *metamode_strs)
+static char *find_metamode_string_by_id(char *metamode_strs, int match_id)
{
char *m;
- const char *str;
for (m = metamode_strs; m && strlen(m); m += strlen(m) +1) {
-
- /* Skip tokens if any */
- str = strstr(m, "::");
+ char *str = strstr(m, "id=");
if (str) {
- str = parse_skip_whitespace(str +2);
- } else {
- str = m;
+ int id = atoi(str+3);
+ if (id && (id == match_id)) {
+ return m;
+ }
}
-
- /* See if metamode strings match */
- if (!strcmp(str, metamode_str)) return m;
}
return NULL;
-
-} /* find_metamode_string() */
+}
@@ -6184,7 +6671,7 @@ static void preprocess_metamodes(nvScreenPtr screen, char *metamode_strs)
{
nvMetaModePtr metamode;
ReturnStatus ret;
- char *str = NULL;
+ char *str;
char *tokens;
int metamode_idx;
@@ -6197,33 +6684,35 @@ static void preprocess_metamodes(nvScreenPtr screen, char *metamode_strs)
free(metamode->string);
metamode->string = screen_get_metamode_str(screen, metamode_idx, 0);
if (!metamode->string) continue;
-
- /* Look for the metamode string in metamode_strs */
- str = find_metamode_string(metamode->string, metamode_strs);
- if (str) {
- /* Grab the metamode id from the tokens */
- tokens = strdup(str);
- if (tokens) {
- char *tmp = strstr(tokens, "::");
- if (tmp) {
- *tmp = '\0';
- parse_token_value_pairs(tokens, apply_metamode_token,
- metamode);
- }
- free(tokens);
- }
+ /* See if the metamode already exists and if so, get its ID */
+ ret = NvCtrlStringOperation(screen->handle, 0,
+ NV_CTRL_STRING_OPERATION_PARSE_METAMODE,
+ metamode->string, &str);
+ if (ret == NvCtrlSuccess) {
+ char *tmp;
- /* The metamode was found, white out the metamode string
- * so it does not get deleted and continue.
+ /* XXX Later, we'll ask X to parse this metamode on updates
+ * and already have an ID so we'll know already which metamodes
+ * need to be deleted/added/moved.
*/
- while (*str) {
- *str = ' ';
- str++;
+
+ tmp = strstr(str, "id=");
+ if (tmp) {
+ int id = atoi(tmp+3);
+ tmp = find_metamode_string_by_id(metamode_strs, id);
+ if (tmp) {
+ metamode->id = id;
+ while (*tmp) {
+ *tmp = ' ';
+ tmp++;
+ }
+ /* Process the next metamode */
+ continue;
+ }
}
- continue;
}
-
+
/* The metamode was not found, so add it to the X screen's list */
tokens = NULL;
ret = NvCtrlStringOperation(screen->handle, 0,
@@ -6374,12 +6863,12 @@ static int update_screen_metamodes(CtkDisplayConfig *ctk_object,
* - Delete any unused mode
* - Move metamodes to the correct location
**/
-
+
/* Get the list of the current metamodes */
ret = NvCtrlGetBinaryAttribute(screen->handle,
0,
- NV_CTRL_BINARY_DATA_METAMODES,
+ NV_CTRL_BINARY_DATA_METAMODES_VERSION_2,
(unsigned char **)&metamode_strs,
&len);
if (ret != NvCtrlSuccess) goto done;
@@ -6387,7 +6876,7 @@ static int update_screen_metamodes(CtkDisplayConfig *ctk_object,
/* Get the current metamode for the screen */
ret = NvCtrlGetStringAttribute(screen->handle,
- NV_CTRL_STRING_CURRENT_METAMODE,
+ NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2,
&cur_metamode_str);
if (ret != NvCtrlSuccess) goto done;
@@ -6402,7 +6891,7 @@ static int update_screen_metamodes(CtkDisplayConfig *ctk_object,
/* Preprocess the new metamodes list */
preprocess_metamodes(screen, metamode_strs);
-
+
/* If we need to switch metamodes, do so now */
if (strcmp(screen->cur_metamode->string, metamode_str)) {
@@ -6413,7 +6902,7 @@ static int update_screen_metamodes(CtkDisplayConfig *ctk_object,
"Switched to MetaMode %dx%d.",
screen->cur_metamode->edim[W],
screen->cur_metamode->edim[H]);
-
+
nv_info_msg(TAB, "Using > %s", screen->cur_metamode->string);
clear_apply = 1;
diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h
index c90c0d5..3371d49 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.h
+++ b/src/gtk+-2.x/ctkdisplayconfig.h
@@ -100,6 +100,8 @@ typedef struct _CtkDisplayConfig
GtkWidget *mnu_display_config_twinview;
/* Display - Settings */
+ GtkWidget *box_screen_drag_info_display;
+
GtkWidget *box_display_resolution;
GtkWidget *mnu_display_resolution;
nvModeLinePtr *resolution_table;
@@ -115,6 +117,19 @@ typedef struct _CtkDisplayConfig
GtkWidget *box_display_stereo;
GtkWidget *mnu_display_stereo;
+ GtkWidget *box_display_orientation;
+ GtkWidget *mnu_display_rotation;
+ GtkWidget *mnu_display_reflection;
+
+ GtkWidget *box_display_viewport;
+
+ GtkWidget *box_display_viewport_in;
+ GtkWidget *txt_display_viewport_in;
+
+ GtkWidget *box_display_viewport_out;
+ GtkWidget *txt_display_viewport_out;
+
+
GtkWidget *box_display_position;
GtkWidget *mnu_display_position_type; /* Absolute, Right of... */
GtkWidget *mnu_display_position_relative; /* List of available devices */
@@ -130,7 +145,7 @@ typedef struct _CtkDisplayConfig
GtkWidget *screen_page;
/* X Screen - Settings */
- GtkWidget *box_screen_drag_info;
+ GtkWidget *box_screen_drag_info_screen;
GtkWidget *box_screen_virtual_size;
GtkWidget *txt_screen_virtual_size;
diff --git a/src/gtk+-2.x/ctkdisplaydevice.c b/src/gtk+-2.x/ctkdisplaydevice.c
index 8ee692b..2249c11 100644
--- a/src/gtk+-2.x/ctkdisplaydevice.c
+++ b/src/gtk+-2.x/ctkdisplaydevice.c
@@ -257,6 +257,7 @@ GtkWidget* ctk_display_device_new(NvCtrlAttributeHandle *handle,
ctk_object->ctk_event_gpu = ctk_event_gpu;
ctk_object->ctk_config = ctk_config;
ctk_object->name = g_strdup(name);
+ ctk_object->color_correction_available = FALSE;
gtk_box_set_spacing(GTK_BOX(object), 10);
@@ -529,6 +530,10 @@ GtkTextBuffer *ctk_display_device_create_help(GtkTextTagTable *table,
add_image_sliders_help
(CTK_IMAGE_SLIDERS(ctk_object->image_sliders), b, &i);
+ if (ctk_object->color_correction_available) {
+ ctk_color_correction_tab_help(b, &i, "X Server Color Correction", TRUE);
+ }
+
td = gtk_tooltips_data_get(GTK_WIDGET(ctk_object->reset_button));
ctk_help_reset_hardware_defaults(b, &i, td->tip_text);
@@ -930,6 +935,7 @@ static void add_color_correction_tab(CtkDisplayDevice *ctk_object,
if (ctk_color_correction == NULL) {
return;
}
+ ctk_object->color_correction_available = TRUE;
box = gtk_hbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(box), FRAME_PADDING);
diff --git a/src/gtk+-2.x/ctkdisplaydevice.h b/src/gtk+-2.x/ctkdisplaydevice.h
index 349d17d..08d59d1 100644
--- a/src/gtk+-2.x/ctkdisplaydevice.h
+++ b/src/gtk+-2.x/ctkdisplaydevice.h
@@ -73,6 +73,8 @@ struct _CtkDisplayDevice
GtkWidget *dithering_controls;
GtkWidget *color_controls;
+ gboolean color_correction_available;
+
InfoEntry *info_entries;
int num_info_entries;
diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c
index 124e246..1735a0b 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.c
+++ b/src/gtk+-2.x/ctkdisplaylayout.c
@@ -409,7 +409,7 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object)
if (ctk_object->modify_info.modify_panning) {
info->target_dim = info->display->cur_mode->pan;
} else {
- info->target_dim = info->display->cur_mode->dim;
+ info->target_dim = info->display->cur_mode->viewPortIn;
}
info->gpu = info->display->gpu;
} else {
@@ -559,10 +559,10 @@ static int get_point_relative_position(int *dim, int x, int y)
/* Offset a single mode */
static void offset_mode(nvModePtr mode, int x, int y)
{
- mode->dim[X] += x;
- mode->dim[Y] += y;
- mode->pan[X] = mode->dim[X];
- mode->pan[Y] = mode->dim[Y];
+ mode->viewPortIn[X] += x;
+ mode->viewPortIn[Y] += y;
+ mode->pan[X] = mode->viewPortIn[X];
+ mode->pan[Y] = mode->viewPortIn[Y];
}
/* Offset a display by offsetting the current mode */
@@ -720,8 +720,8 @@ static void resolve_displays_in_screen(nvScreenPtr screen,
for (mode_idx = first_idx; mode_idx <= last_idx; mode_idx++) {
if (resolve_display(display, mode_idx, pos)) {
nvModePtr mode = get_mode(display, mode_idx);
- mode->dim[X] = pos[X];
- mode->dim[Y] = pos[Y];
+ mode->viewPortIn[X] = pos[X];
+ mode->viewPortIn[Y] = pos[Y];
mode->pan[X] = pos[X];
mode->pan[Y] = pos[Y];
}
@@ -910,7 +910,7 @@ static void calc_metamode(nvScreenPtr screen, nvMetaModePtr metamode)
if (mode->metamode == metamode) break;
}
if (!mode) continue;
-
+
if (init) {
dim[X] = mode->pan[X];
dim[Y] = mode->pan[Y];
@@ -918,11 +918,11 @@ static void calc_metamode(nvScreenPtr screen, nvMetaModePtr metamode)
dim[H] = mode->pan[Y] +mode->pan[H];
init = 0;
} else {
- dim[X] = MIN(dim[X], mode->dim[X]);
- dim[Y] = MIN(dim[Y], mode->dim[Y]);
- dim[W] = MAX(dim[W], mode->dim[X] +mode->pan[W]);
- dim[H] = MAX(dim[H], mode->dim[Y] +mode->pan[H]);
- }
+ dim[X] = MIN(dim[X], mode->viewPortIn[X]);
+ dim[Y] = MIN(dim[Y], mode->viewPortIn[Y]);
+ dim[W] = MAX(dim[W], mode->viewPortIn[X] +mode->pan[W]);
+ dim[H] = MAX(dim[H], mode->viewPortIn[Y] +mode->pan[H]);
+ }
/* Don't include NULL modes in the effective dimension calculation */
if (!mode->modeline) continue;
@@ -934,10 +934,10 @@ static void calc_metamode(nvScreenPtr screen, nvMetaModePtr metamode)
edim[H] = mode->pan[Y] +mode->pan[H];
einit = 0;
} else {
- edim[X] = MIN(edim[X], mode->dim[X]);
- edim[Y] = MIN(edim[Y], mode->dim[Y]);
- edim[W] = MAX(edim[W], mode->dim[X] +mode->pan[W]);
- edim[H] = MAX(edim[H], mode->dim[Y] +mode->pan[H]);
+ edim[X] = MIN(edim[X], mode->viewPortIn[X]);
+ edim[Y] = MIN(edim[Y], mode->viewPortIn[Y]);
+ edim[W] = MAX(edim[W], mode->viewPortIn[X] +mode->pan[W]);
+ edim[H] = MAX(edim[H], mode->viewPortIn[Y] +mode->pan[H]);
}
}
@@ -1068,14 +1068,14 @@ static void calc_layout(nvLayoutPtr layout)
display = display->next_on_gpu) {
if (display->screen) continue;
- display->cur_mode->dim[X] = x;
+ display->cur_mode->viewPortIn[X] = x;
display->cur_mode->pan[X] = x;
- display->cur_mode->dim[Y] = y;
+ display->cur_mode->viewPortIn[Y] = y;
display->cur_mode->pan[Y] = y;
- x += display->cur_mode->dim[W];
- dim[W] += display->cur_mode->dim[W];
- dim[H] = MAX(dim[H], display->cur_mode->dim[H]);
+ x += display->cur_mode->viewPortIn[W];
+ dim[W] += display->cur_mode->viewPortIn[W];
+ dim[H] = MAX(dim[H], display->cur_mode->viewPortIn[H]);
}
}
@@ -1503,7 +1503,7 @@ static void snap_move(CtkDisplayLayout *ctk_object)
/* Snap to other display's dimensions */
snap_dim_to_dim(info->dst_dim,
info->src_dim,
- other->cur_mode->dim,
+ other->cur_mode->viewPortIn,
ctk_object->snap_strength, bv, bh);
}
@@ -1542,7 +1542,7 @@ static void snap_move(CtkDisplayLayout *ctk_object)
*/
if (!bh &&
info->display &&
- info->display->cur_mode->dim[Y] == info->screen->dim[Y]) {
+ info->display->cur_mode->viewPortIn[Y] == info->screen->dim[Y]) {
bv = NULL;
}
@@ -1563,7 +1563,7 @@ static void snap_move(CtkDisplayLayout *ctk_object)
*/
if (!bv &&
info->display &&
- info->display->cur_mode->dim[X] == info->screen->dim[X]) {
+ info->display->cur_mode->viewPortIn[X] == info->screen->dim[X]) {
bh = NULL;
}
@@ -1626,34 +1626,34 @@ static void snap_pan(CtkDisplayLayout *ctk_object)
if (info->display) {
+ int *cur_mode_dim = info->display->cur_mode->viewPortIn;
+
/* Snap to multiples of the display's dimensions */
bh = &(info->best_snap_h);
bv = &(info->best_snap_v);
- dist = info->src_dim[W] % info->display->cur_mode->dim[W];
+ dist = info->src_dim[W] % cur_mode_dim[W];
if (dist < *bh) {
- info->dst_dim[W] = info->display->cur_mode->dim[W] *
- (int)(info->src_dim[W] / info->display->cur_mode->dim[W]);
+ info->dst_dim[W] = cur_mode_dim[W] *
+ (int)(info->src_dim[W] / cur_mode_dim[W]);
*bh = dist;
}
- dist = info->display->cur_mode->dim[W] -
- (info->src_dim[W] % info->display->cur_mode->dim[W]);
+ dist = cur_mode_dim[W] - (info->src_dim[W] % cur_mode_dim[W]);
if (dist < *bh) {
- info->dst_dim[W] = info->display->cur_mode->dim[W] *
- (1 + (int)(info->src_dim[W] / info->display->cur_mode->dim[W]));
+ info->dst_dim[W] = cur_mode_dim[W] *
+ (1 + (int)(info->src_dim[W] / cur_mode_dim[W]));
*bh = dist;
}
- dist = abs(info->src_dim[H] % info->display->cur_mode->dim[H]);
+ dist = abs(info->src_dim[H] % cur_mode_dim[H]);
if (dist < *bv) {
- info->dst_dim[H] = info->display->cur_mode->dim[H] *
- (int)(info->src_dim[H] / info->display->cur_mode->dim[H]);
+ info->dst_dim[H] = cur_mode_dim[H] *
+ (int)(info->src_dim[H] / cur_mode_dim[H]);
*bv = dist;
}
- dist = info->display->cur_mode->dim[H] -
- (info->src_dim[H] % info->display->cur_mode->dim[H]);
+ dist = cur_mode_dim[H] - (info->src_dim[H] % cur_mode_dim[H]);
if (dist < *bv) {
- info->dst_dim[H] = info->display->cur_mode->dim[H] *
- (1 + (int)(info->src_dim[H] / info->display->cur_mode->dim[H]));
+ info->dst_dim[H] = cur_mode_dim[H] *
+ (1 + (int)(info->src_dim[H] / cur_mode_dim[H]));
*bv = dist;
}
}
@@ -1729,11 +1729,11 @@ static void snap_pan(CtkDisplayLayout *ctk_object)
info->src_dim,
other->cur_mode->pan,
bv, bh);
-
+
/* Snap to other display dimensions */
snap_side_to_dim(info->dst_dim,
info->src_dim,
- other->cur_mode->dim,
+ other->cur_mode->viewPortIn,
bv, bh);
}
@@ -1842,7 +1842,7 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
ctk_object->scale;
if (info->display) {
- dim = info->display->cur_mode->relative_to->cur_mode->dim;
+ dim = info->display->cur_mode->relative_to->cur_mode->viewPortIn;
} else {
dim = get_screen_dim(info->screen->relative_to, 0);
}
@@ -1978,8 +1978,8 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
} else {
/* Move the display to its destination */
- info->display->cur_mode->dim[X] = info->dst_dim[X];
- info->display->cur_mode->dim[Y] = info->dst_dim[Y];
+ info->display->cur_mode->viewPortIn[X] = info->dst_dim[X];
+ info->display->cur_mode->viewPortIn[Y] = info->dst_dim[Y];
info->display->cur_mode->pan[X] = info->dst_dim[X];
info->display->cur_mode->pan[Y] = info->dst_dim[Y];
@@ -2092,7 +2092,7 @@ static int pan_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
/* Don't allow the panning domain to get too small */
if (info->display) {
- dim = info->display->cur_mode->dim;
+ dim = info->display->cur_mode->viewPortIn;
if (info->modify_dim[W] < dim[W]) {
info->modify_dim[W] = dim[W];
}
@@ -2158,8 +2158,8 @@ static int pan_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
/* Panning domain can never be smaller then the display viewport */
if (info->display) {
- dim = info->display->cur_mode->dim;
- if (info->dst_dim[W] < dim[W]) {
+ dim = info->display->cur_mode->viewPortIn;
+ if (info->dst_dim[W] < dim[W]) {
info->dst_dim[W] = dim[W];
}
if (info->dst_dim[H] < dim[H]) {
@@ -2359,7 +2359,7 @@ static void select_default_item(CtkDisplayLayout *ctk_object)
int best_dst = -1; // Distance squared to element.
int dst;
-
+
for (i = 0; i < ctk_object->Zcount; i++) {
if (ctk_object->Zorder[i].type == ZNODE_TYPE_DISPLAY) {
@@ -2368,13 +2368,13 @@ static void select_default_item(CtkDisplayLayout *ctk_object)
/* Ignore disabled displays */
if (!display->cur_mode) continue;
- dst = DIST_SQR(display->cur_mode->dim);
+ dst = DIST_SQR(display->cur_mode->viewPortIn);
if (best_dst < 0 || dst < best_dst) {
best_dst = dst;
sel_display = display;
sel_screen = NULL;
}
-
+
} else if (ctk_object->Zorder[i].type == ZNODE_TYPE_SCREEN) {
screen = ctk_object->Zorder[i].u.screen;
@@ -3048,21 +3048,22 @@ static void draw_display(CtkDisplayLayout *ctk_object,
/* Draw viewport */
color_idx = base_color_idx + ((mode->modeline) ? BG_SCR_ON : BG_SCR_OFF);
- draw_rect(ctk_object, mode->dim, &(ctk_object->color_palettes[color_idx]),
+ draw_rect(ctk_object, mode->viewPortIn, &(ctk_object->color_palettes[color_idx]),
1);
- draw_rect(ctk_object, mode->dim, &(ctk_object->fg_color), 0);
+ draw_rect(ctk_object, mode->viewPortIn, &(ctk_object->fg_color), 0);
/* Draw text information */
if (!mode->display->screen) {
tmp_str = g_strdup("(Disabled)");
} else if (mode->modeline) {
- tmp_str = g_strdup_printf("%dx%d", mode->dim[W], mode->dim[H]);
+ tmp_str = g_strdup_printf("%dx%d", mode->viewPortIn[W],
+ mode->viewPortIn[H]);
} else {
tmp_str = g_strdup("(Off)");
}
draw_rect_strs(ctk_object,
- mode->dim,
+ mode->viewPortIn,
&(ctk_object->fg_color),
display->logName,
tmp_str);
@@ -3165,7 +3166,7 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
int *dim;
if (ctk_object->selected_display) {
- dim = ctk_object->selected_display->cur_mode->dim;
+ dim = ctk_object->selected_display->cur_mode->viewPortIn;
} else {
dim = get_screen_dim(ctk_object->selected_screen, 0);
}
@@ -3217,7 +3218,7 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
// with display devices that are "off"
gdk_color_parse("#0000FF", &bg_color);
draw_rect(ctk_object,
- ctk_object->selected_screen->cur_metamode->dim,
+ ctk_object->selected_screen->cur_metamode->viewPortIn,
&(bg_color), 0);
// Shows the current screen dimensions used for relative
@@ -3363,6 +3364,9 @@ void ctk_display_layout_set_layout(CtkDisplayLayout *ctk_object,
{
/* Setup for the new layout */
ctk_object->layout = layout;
+
+ sync_layout(layout);
+ sync_scaling(ctk_object);
zorder_layout(ctk_object);
select_default_item(ctk_object);
@@ -3462,7 +3466,6 @@ void ctk_display_layout_set_screen_metamode(CtkDisplayLayout *ctk_object,
set_screen_metamode(ctk_object->layout, screen, new_metamode_idx);
recenter_layout(ctk_object->layout);
sync_scaling(ctk_object);
- ctk_object->modify_info.modify_dirty = 1;
/* Update the layout */
ctk_display_layout_update(ctk_object);
@@ -3511,25 +3514,14 @@ void ctk_display_layout_add_screen_metamode(CtkDisplayLayout *ctk_object,
mode = (nvModePtr)calloc(1, sizeof(nvMode));
if (!mode) goto fail;
- /* Link the mode to the metamode */
- mode->metamode = metamode;
-
/* Duplicate the currently selected mode */
- mode->display = display;
if (display->cur_mode) {
- mode->modeline = display->cur_mode->modeline;
- mode->dim[X] = display->cur_mode->dim[X];
- mode->dim[Y] = display->cur_mode->dim[Y];
- mode->dim[W] = display->cur_mode->dim[W];
- mode->dim[H] = display->cur_mode->dim[H];
- mode->pan[X] = display->cur_mode->pan[X];
- mode->pan[Y] = display->cur_mode->pan[Y];
- mode->pan[W] = display->cur_mode->pan[W];
- mode->pan[H] = display->cur_mode->pan[H];
- mode->position_type = display->cur_mode->position_type;
- mode->relative_to = display->cur_mode->relative_to;
+ memcpy(mode, display->cur_mode, sizeof(*mode));
}
+ /* Link the mode to the metamode */
+ mode->metamode = metamode;
+
/* Add the mode after the currently selected mode */
mode->next = display->cur_mode->next;
display->cur_mode->next = mode;
@@ -3718,32 +3710,10 @@ void ctk_display_layout_set_mode_modeline(CtkDisplayLayout *ctk_object,
/* Setup the mode's dimensions based on the modeline */
if (modeline) {
- mode->dim[W] = modeline->data.hdisplay;
- mode->dim[H] = modeline->data.vdisplay;
-
- if (mode->pan[W] < modeline->data.hdisplay) {
- mode->pan[W] = modeline->data.hdisplay;
- }
- if (mode->pan[H] < modeline->data.vdisplay) {
- mode->pan[H] = modeline->data.vdisplay;
- }
-
- /* If the old modeline did not have panning dimensions */
- if (!old_modeline ||
- (mode->pan[W] == old_modeline->data.hdisplay)) {
- mode->pan[W] = modeline->data.hdisplay;
- }
- if (!old_modeline ||
- (mode->pan[H] == old_modeline->data.vdisplay)) {
- mode->pan[H] = modeline->data.vdisplay;
- }
-
+ mode_set_dims_from_modeline(mode, modeline);
} else if (mode->display) {
/* Display is being turned off, set the default width/height */
- mode->dim[W] = mode->display->modelines->data.hdisplay;
- mode->dim[H] = mode->display->modelines->data.vdisplay;
- mode->pan[W] = mode->display->modelines->data.hdisplay;
- mode->pan[H] = mode->display->modelines->data.vdisplay;
+ mode_set_dims_from_modeline(mode, mode->display->modelines);
}
/* In advanced mode, changing the resolution a display uses for a
@@ -3762,6 +3732,137 @@ void ctk_display_layout_set_mode_modeline(CtkDisplayLayout *ctk_object,
} /* ctk_display_layout_set_display_modeline() */
+/*!
+ * Sets the ViewPort In for the given mode.
+ *
+ * If a modification occurs, this function will call the modified_callback
+ * handler registered, if any.
+ *
+ * \param[in] ctk_object The Display Layout object
+ * \param[in] mode The mode to be modified
+ * \param[in] w The width of the ViewPort In to set
+ * \param[in] h The height of the ViewPort In to set
+ */
+void ctk_display_layout_set_mode_viewport_in(CtkDisplayLayout *ctk_object,
+ nvModePtr mode,
+ int w, int h)
+{
+ Bool modified = TRUE;
+
+ if (!mode || !mode->modeline) {
+ return;
+ }
+
+ if (w < 1) {
+ w = 1;
+ }
+ if (h < 1) {
+ h = 1;
+ }
+
+ mode->viewPortIn[W] = w;
+ mode->viewPortIn[H] = h;
+
+ /* Clamp the panning domain to the new viewport dimensions */
+ if (mode->pan[W] < mode->viewPortIn[W]) {
+ mode->pan[W] = mode->viewPortIn[W];
+ }
+ if (mode->pan[H] < mode->viewPortIn[H]) {
+ mode->pan[H] = mode->viewPortIn[H];
+ }
+
+ if (modified) {
+ /* Update the layout */
+ ctk_display_layout_update(ctk_object);
+
+ /* Notify the modification */
+ if (ctk_object->modified_callback) {
+ ctk_object->modified_callback(ctk_object->layout,
+ ctk_object->modified_callback_data);
+ }
+ }
+}
+
+
+/*!
+ * Sets the ViewPort Out for the given mode.
+ *
+ * If a modification occurs, this function will call the modified_callback
+ * handler registered, if any.
+ *
+ * \param[in] ctk_object The Display Layout object
+ * \param[in] mode The mode to be modified
+ * \param[in] x The X offset of the ViewPort Out to set
+ * \param[in] y The Y offset of the ViewPort Out to set
+ * \param[in] w The width of the ViewPort Out to set
+ * \param[in] h The height of the ViewPort Out to set
+ */
+void ctk_display_layout_set_mode_viewport_out(CtkDisplayLayout *ctk_object,
+ nvModePtr mode,
+ int x, int y, int w, int h)
+{
+ Bool modified = TRUE;
+ int extra;
+
+ if (!mode || !mode->modeline) {
+ return;
+ }
+
+ /* Clamp ViewPortOut to raster size. If the ViewPortOut extends past the
+ * raster size, reduce the ViewPortOut offset before reducing the
+ * dimensions
+ */
+ extra = (x + w) - mode->modeline->data.hdisplay;
+ if (extra > 0) {
+ if (extra > x) {
+ w = mode->modeline->data.hdisplay;
+ x = 0;
+ } else {
+ x -= extra;
+ }
+ }
+
+ extra = (y + h) - mode->modeline->data.vdisplay;
+ if (extra > 0) {
+ if (extra > y) {
+ h = mode->modeline->data.vdisplay;
+ y = 0;
+ } else {
+ y -= extra;
+ }
+ }
+
+ if (w < 1) {
+ w = 1;
+ }
+ if (h < 1) {
+ h = 1;
+ }
+ if (x < 0) {
+ x = 0;
+ }
+ if (y < 0) {
+ y = 0;
+ }
+
+ mode->viewPortOut[X] = x;
+ mode->viewPortOut[Y] = y;
+ mode->viewPortOut[W] = w;
+ mode->viewPortOut[H] = h;
+
+ if (modified) {
+ /* Update the layout */
+ ctk_display_layout_update(ctk_object);
+
+ /* Notify the modification */
+ if (ctk_object->modified_callback) {
+ ctk_object->modified_callback(ctk_object->layout,
+ ctk_object->modified_callback_data);
+ }
+ }
+}
+
+
/** ctk_display_layout_set_display_position() ************************
*
@@ -3838,15 +3939,15 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
/* Do the move by offsetting */
ctk_object->modify_info.modify_dirty = 1;
modified = move_selected(ctk_object,
- x - display->cur_mode->dim[X],
- y - display->cur_mode->dim[Y],
+ x - display->cur_mode->viewPortIn[X],
+ y - display->cur_mode->viewPortIn[Y],
0);
/* Report back result of move */
if (ctk_object->modified_callback &&
(modified ||
- x != display->cur_mode->dim[X] ||
- y != display->cur_mode->dim[Y])) {
+ x != display->cur_mode->viewPortIn[X] ||
+ y != display->cur_mode->viewPortIn[Y])) {
ctk_object->modified_callback
(ctk_object->layout, ctk_object->modified_callback_data);
}
@@ -3904,6 +4005,112 @@ void ctk_display_layout_set_display_panning(CtkDisplayLayout *ctk_object,
+/*!
+ * Sets the rotation orientation for the display.
+ *
+ * In basic mode, this function will make all modes on the display have the
+ * same rotation. In advanced mode, only the current mode will have its
+ * rotation orientation modified.
+ *
+ * If a modification occurs, this function will call the modified_callback
+ * handler registered, if any.
+ *
+ * \param[in] ctk_object The Display Layout object
+ * \param[in] display The display who's modes are to be modified
+ * \param[in] rotation The rotation to set
+ */
+void ctk_display_layout_set_display_rotation(CtkDisplayLayout *ctk_object,
+ nvDisplayPtr display,
+ Rotation rotation)
+{
+ Bool modified;
+
+
+ if (!display->cur_mode ||
+ !display->cur_mode->modeline) {
+ return;
+ }
+
+ if (ctk_object->advanced_mode) {
+ /* In advanced mode, only set the rotation of the current mode */
+ modified = mode_set_rotation(display->cur_mode, rotation);
+ } else {
+ /* In basic mode, make all the modes have the same rotation */
+ modified = display_set_modes_rotation(display, rotation);
+ }
+
+ if (modified) {
+ /* Update the layout */
+ ctk_display_layout_update(ctk_object);
+
+ /* Notify the modification */
+ if (ctk_object->modified_callback) {
+ ctk_object->modified_callback(ctk_object->layout,
+ ctk_object->modified_callback_data);
+ }
+ }
+}
+
+
+
+/*!
+ * Sets the reflection orientation for the display.
+ *
+ * In basic mode, this function will make all modes on the display have the
+ * same reflection. In advanced mode, only the current mode will have its
+ * reflection orientation modified.
+ *
+ * If a modification occurs, this function will call the modified_callback
+ * handler registered, if any.
+ *
+ * \param[in] ctk_object The Display Layout object
+ * \param[in] display The display who's modes are to be modified
+ * \param[in] reflection The reflection to set
+ */
+void ctk_display_layout_set_display_reflection(CtkDisplayLayout *ctk_object,
+ nvDisplayPtr display,
+ Reflection reflection)
+{
+ Bool modified;
+
+
+ if (!display->cur_mode ||
+ !display->cur_mode->modeline) {
+ return;
+ }
+
+ if (ctk_object->advanced_mode) {
+ /* In advanced mode, only set the reflection of the current mode */
+ if (display->cur_mode->reflection != reflection) {
+ modified = TRUE;
+ }
+ display->cur_mode->reflection = reflection;
+ } else {
+ nvModePtr mode;
+
+ /* In basic mode, make all the modes have the same reflection */
+ for (mode = display->modes; mode; mode = mode->next) {
+ if (mode->reflection != reflection) {
+ mode->reflection = reflection;
+ modified = TRUE;
+ }
+ }
+ }
+
+ if (modified) {
+ /* Update the layout */
+ ctk_display_layout_update(ctk_object);
+
+ /* Notify the modification */
+ if (ctk_object->modified_callback) {
+ ctk_object->modified_callback(ctk_object->layout,
+ ctk_object->modified_callback_data);
+ }
+ }
+}
+
+
+
/** select_topmost_item() **************************************
*
* Select top item from Z order list.
diff --git a/src/gtk+-2.x/ctkdisplaylayout.h b/src/gtk+-2.x/ctkdisplaylayout.h
index 31e3455..b6e53c9 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.h
+++ b/src/gtk+-2.x/ctkdisplaylayout.h
@@ -131,6 +131,20 @@ typedef enum {
} PassiveStereoEye;
typedef enum {
+ ROTATION_0 = 0,
+ ROTATION_90,
+ ROTATION_180,
+ ROTATION_270,
+} Rotation;
+
+typedef enum {
+ REFLECTION_NONE = 0,
+ REFLECTION_X,
+ REFLECTION_Y,
+ REFLECTION_XY,
+} Reflection;
+
+typedef enum {
METAMODE_SOURCE_XCONFIG = 0,
METAMODE_SOURCE_IMPLICIT,
METAMODE_SOURCE_NVCONTROL,
@@ -152,7 +166,13 @@ typedef struct nvModeLineRec {
-/* Mode (A particular configuration for a display within an X screen) */
+/* Mode (A particular configuration for a display within an X screen)
+ *
+ * NOTE: When metamodes are duplicated, the modes are memcpy'ed over, so
+ * if new variables are added to the nvModeRec that shouldn't (just)
+ * be copied, be sure to update this in
+ * ctk_display_layout_add_screen_metamode().
+ */
typedef struct nvModeRec {
struct nvModeRec *next;
@@ -169,14 +189,20 @@ typedef struct nvModeRec {
struct nvModeLineRec *modeline; /* Modeline this mode references */
int dummy; /* Dummy mode, don't print out */
- int dim[4]; /* Viewport (absolute) */
+ int viewPortIn[4]; /* Viewport In (absolute) */
int pan[4]; /* Panning Domain (absolute) */
+ int viewPortOut[4]; /* ViewPort Out (WH) */
+
int position_type; /* Relative, Absolute, etc. */
struct nvDisplayRec *relative_to; /* Display Relative/RightOf etc */
PassiveStereoEye passive_stereo_eye; /* Stereo mode 4 per-dpy setting */
+
+ Rotation rotation;
+ Reflection reflection;
+
} nvMode, *nvModePtr;
@@ -494,6 +520,14 @@ void ctk_display_layout_set_mode_modeline (CtkDisplayLayout *,
nvModePtr mode,
nvModeLinePtr modeline);
+void ctk_display_layout_set_mode_viewport_in(CtkDisplayLayout *ctk_object,
+ nvModePtr mode,
+ int w, int h);
+
+void ctk_display_layout_set_mode_viewport_out(CtkDisplayLayout *ctk_object,
+ nvModePtr mode,
+ int x, int y, int w, int h);
+
void ctk_display_layout_set_display_position (CtkDisplayLayout *ctk_object,
nvDisplayPtr display,
int position_type,
@@ -502,6 +536,15 @@ void ctk_display_layout_set_display_position (CtkDisplayLayout *ctk_object,
void ctk_display_layout_set_display_panning (CtkDisplayLayout *ctk_object,
nvDisplayPtr display,
int width, int height);
+
+void ctk_display_layout_set_display_rotation (CtkDisplayLayout *ctk_object,
+ nvDisplayPtr display,
+ Rotation rotation);
+
+void ctk_display_layout_set_display_reflection (CtkDisplayLayout *ctk_object,
+ nvDisplayPtr display,
+ Reflection reflection);
+
void ctk_display_layout_select_display (CtkDisplayLayout *ctk_object,
nvDisplayPtr display);
void ctk_display_layout_select_screen (CtkDisplayLayout *ctk_object,
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index 6903af0..8a7956a 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -327,6 +327,8 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_FRAMELOCK_INCOMING_HOUSE_SYNC_RATE);
MAKE_SIGNAL(NV_CTRL_FXAA);
MAKE_SIGNAL(NV_CTRL_DISPLAY_RANDR_OUTPUT_ID);
+ MAKE_SIGNAL(NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY);
+ MAKE_SIGNAL(NV_CTRL_USED_DEDICATED_GPU_MEMORY);
#undef MAKE_SIGNAL
/*
@@ -336,7 +338,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DISPLAY_RANDR_OUTPUT_ID
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_USED_DEDICATED_GPU_MEMORY
#warning "There are attributes that do not emit signals!"
#endif
@@ -419,9 +421,10 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_DISPLAYS_CONNECTED_TO_GPU);
MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_METAMODES_VERSION_2);
MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN);
+ MAKE_BINARY_SIGNAL(NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN);
#undef MAKE_BINARY_SIGNAL
-#if NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE != NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN
+#if NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE != NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN
#warning "There are attributes that do not emit signals!"
#endif
diff --git a/src/gtk+-2.x/ctkgpu.c b/src/gtk+-2.x/ctkgpu.c
index 929b1c4..7f4a1b7 100644
--- a/src/gtk+-2.x/ctkgpu.c
+++ b/src/gtk+-2.x/ctkgpu.c
@@ -35,7 +35,10 @@
static void probe_displays_received(GtkObject *object, gpointer arg1,
gpointer user_data);
+static gboolean update_gpu_memory_used(gpointer);
+
#define ARRAY_ELEMENTS 16
+#define DEFAULT_UPDATE_GPU_INFO_TIME_INTERVAL 3000
GType ctk_gpu_get_type(
void
@@ -188,7 +191,7 @@ GtkWidget* ctk_gpu_new(
GtkWidget *hseparator;
GtkWidget *table;
- char *product_name, *vbios_version, *video_ram, *irq;
+ char *product_name, *vbios_version, *video_ram, *gpu_memory_text, *irq;
gchar *pci_bus_id;
gchar pci_device_id[ARRAY_ELEMENTS];
gchar pci_vendor_id[ARRAY_ELEMENTS];
@@ -212,7 +215,8 @@ GtkWidget* ctk_gpu_new(
int len;
int i;
int row = 0;
- int total_rows = 19;
+ int total_rows = 21;
+ int gpu_memory;
/*
@@ -268,6 +272,16 @@ GtkWidget* ctk_gpu_new(
} else {
video_ram = g_strdup_printf("%d MB", tmp >> 10);
}
+
+ /* NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY */
+
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY,
+ &gpu_memory);
+ if (ret != NvCtrlSuccess) {
+ gpu_memory_text = NULL;
+ } else {
+ gpu_memory_text = g_strdup_printf("%d MB", gpu_memory);
+ }
/* NV_CTRL_GPU_CORES */
@@ -363,6 +377,7 @@ GtkWidget* ctk_gpu_new(
ctk_gpu->ctk_config = ctk_config;
ctk_gpu->ctk_event = ctk_event;
ctk_gpu->pcie_gen_queriable = FALSE;
+ ctk_gpu->gpu_memory = gpu_memory;
/* set container properties of the object */
@@ -424,8 +439,16 @@ GtkWidget* ctk_gpu_new(
0, 0.5, "VBIOS Version:",
0, 0.5, vbios_version);
add_table_row(table, row++,
- 0, 0.5, "Memory:",
+ 0, 0.5, "Total Memory:",
0, 0.5, video_ram);
+ add_table_row(table, row++,
+ 0, 0.5, "Total Dedicated Memory:",
+ 0, 0.5, gpu_memory_text);
+ ctk_gpu->gpu_memory_used_label =
+ add_table_row(table, row++,
+ 0, 0.5, "Used Dedicated Memory:",
+ 0, 0.5, NULL);
+ update_gpu_memory_used(ctk_gpu);
if ( ctk_gpu->memory_interface ) {
gtk_table_resize(GTK_TABLE(table), ++total_rows, 2);
add_table_row(table, row++,
@@ -491,6 +514,7 @@ GtkWidget* ctk_gpu_new(
g_free(screens);
g_free(displays);
g_free(bus);
+ g_free(gpu_memory_text);
gtk_widget_show_all(GTK_WIDGET(object));
@@ -501,6 +525,16 @@ GtkWidget* ctk_gpu_new(
G_CALLBACK(probe_displays_received),
(gpointer) ctk_gpu);
+ tmp_str = g_strdup_printf("Memory Used (GPU %d)",
+ NvCtrlGetTargetId(handle));
+
+ ctk_config_add_timer(ctk_gpu->ctk_config,
+ DEFAULT_UPDATE_GPU_INFO_TIME_INTERVAL,
+ tmp_str,
+ (GSourceFunc) update_gpu_memory_used,
+ (gpointer) ctk_gpu);
+ g_free(tmp_str);
+
return GTK_WIDGET(object);
}
@@ -534,7 +568,7 @@ GtkTextBuffer *ctk_gpu_create_help(GtkTextTagTable *table,
ctk_help_heading(b, &i, "VBIOS Version");
ctk_help_para(b, &i, "This is the Video BIOS version.");
- ctk_help_heading(b, &i, "Memory");
+ ctk_help_heading(b, &i, "Total Memory");
ctk_help_para(b, &i, "This is the overall amount of memory "
"available to your GPU. With TurboCache(TM) GPUs, "
"this value may exceed the amount of video "
@@ -543,6 +577,14 @@ GtkTextBuffer *ctk_gpu_create_help(GtkTextTagTable *table,
"dedicated system memory set aside by the system "
"BIOS for use by the integrated GPU.");
+ ctk_help_heading(b, &i, "Total Dedicated Memory");
+ ctk_help_para(b, &i, "This is the amount of memory dedicated "
+ "exclusively to your GPU.");
+
+ ctk_help_heading(b, &i, "Used Dedicated Memory");
+ ctk_help_para(b, &i, "This is the amount of dedicated memory used "
+ "by your GPU.");
+
if (ctk_gpu->memory_interface) {
ctk_help_heading(b, &i, "Memory Interface");
ctk_help_para(b, &i, "This is the bus bandwidth of the GPU's "
@@ -622,4 +664,60 @@ static void probe_displays_received(GtkObject *object, gpointer arg1,
g_free(str);
}
+static gboolean update_gpu_memory_used(gpointer user_data)
+{
+ CtkGpu *ctk_gpu;
+ gchar *memory_text;
+ ReturnStatus ret;
+ int value;
+ static int num_failures = 0;
+
+ ctk_gpu = CTK_GPU(user_data);
+
+ ret = NvCtrlGetAttribute(ctk_gpu->handle,
+ NV_CTRL_USED_DEDICATED_GPU_MEMORY,
+ &value);
+ if (ret != NvCtrlSuccess || value > ctk_gpu->gpu_memory || value < 0) {
+ gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_memory_used_label), "Unknown");
+ if(num_failures++ >= 10) {
+ return FALSE;
+ }
+ } else {
+ if (ctk_gpu->gpu_memory > 0) {
+ memory_text = g_strdup_printf("%d MB (%.0f%%)",
+ value,
+ 100.0 * (double) value /
+ (double) ctk_gpu->gpu_memory);
+ } else {
+ memory_text = g_strdup_printf("%d MB", value);
+ }
+
+ gtk_label_set_text(GTK_LABEL(ctk_gpu->gpu_memory_used_label), memory_text);
+ g_free(memory_text);
+ }
+
+ return TRUE;
+}
+
+void ctk_gpu_page_select(GtkWidget *widget)
+{
+ CtkGpu *ctk_gpu = CTK_GPU(widget);
+
+ /* Start the gpu timer */
+
+ ctk_config_start_timer(ctk_gpu->ctk_config,
+ (GSourceFunc) update_gpu_memory_used,
+ (gpointer) ctk_gpu);
+}
+
+void ctk_gpu_page_unselect(GtkWidget *widget)
+{
+ CtkGpu *ctk_gpu = CTK_GPU(widget);
+
+ /* Stop the gpu timer */
+
+ ctk_config_stop_timer(ctk_gpu->ctk_config,
+ (GSourceFunc) update_gpu_memory_used,
+ (gpointer) ctk_gpu);
+}
diff --git a/src/gtk+-2.x/ctkgpu.h b/src/gtk+-2.x/ctkgpu.h
index 5bee1da..eb95a0d 100644
--- a/src/gtk+-2.x/ctkgpu.h
+++ b/src/gtk+-2.x/ctkgpu.h
@@ -60,6 +60,8 @@ struct _CtkGpu
CtkEvent *ctk_event;
GtkWidget *displays;
+ GtkWidget *gpu_memory_used_label;
+ gint gpu_memory;
gint gpu_cores;
gint memory_interface;
gboolean pcie_gen_queriable;
@@ -84,6 +86,9 @@ void get_bus_id_str(NvCtrlAttributeHandle *handle,
GtkTextBuffer *ctk_gpu_create_help(GtkTextTagTable *,
CtkGpu *);
+void ctk_gpu_page_select(GtkWidget *);
+void ctk_gpu_page_unselect(GtkWidget *);
+
G_END_DECLS
#endif /* __CTK_GPU_H__ */
diff --git a/src/gtk+-2.x/ctkmultisample.c b/src/gtk+-2.x/ctkmultisample.c
index 8f439b8..050240d 100644
--- a/src/gtk+-2.x/ctkmultisample.c
+++ b/src/gtk+-2.x/ctkmultisample.c
@@ -171,6 +171,7 @@ static const char *__texture_sharpening_help =
#define __FSAA_32x (__FSAA << NV_CTRL_FSAA_MODE_32x)
#define __FSAA_64xS (__FSAA << NV_CTRL_FSAA_MODE_64xS)
#define __FSAA_ENHANCE (__FSAA << (NV_CTRL_FSAA_MODE_MAX + 1))
+#define __FXAA (__FSAA << (NV_CTRL_FSAA_MODE_MAX + 2))
#define FRAME_PADDING 5
@@ -371,7 +372,7 @@ GtkWidget *ctk_multisample_new(NvCtrlAttributeHandle *handle,
for (i = 0; i < ctk_multisample->fsaa_translation_table_size; i++)
ctk_multisample->active_attributes |=
- (1 << (__FSAA+ctk_multisample->fsaa_translation_table[i]));
+ (__FSAA << ctk_multisample->fsaa_translation_table[i]);
/* FXAA Option button */
@@ -401,6 +402,8 @@ GtkWidget *ctk_multisample_new(NvCtrlAttributeHandle *handle,
ctk_config_set_tooltip(ctk_config, check_button,
__fxaa_enable_help);
gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
+
+ ctk_multisample->active_attributes |= __FXAA;
ctk_multisample->fxaa_enable_check_button = check_button;
}
}
@@ -1641,6 +1644,11 @@ GtkTextBuffer *ctk_multisample_create_help(GtkTextTagTable *table,
}
}
+ if (ctk_multisample->active_attributes & __FXAA) {
+ ctk_help_term(b, &i, "Enable FXAA");
+ ctk_help_para(b, &i, __fxaa_enable_help);
+ }
+
if (ctk_multisample->active_attributes & __LOG_ANISO_RANGE) {
ctk_help_heading(b, &i, "Anisotropic Filtering");
diff --git a/src/gtk+-2.x/ctkscreen.c b/src/gtk+-2.x/ctkscreen.c
index e486eeb..e29f7b1 100644
--- a/src/gtk+-2.x/ctkscreen.c
+++ b/src/gtk+-2.x/ctkscreen.c
@@ -47,6 +47,7 @@ static const _CtkStereoMode stereoMode[] = {
{ NV_CTRL_STEREO_INVERSE_CHECKERBOARD_PATTERN, "Inverse Checkerboard Stereo" },
{ NV_CTRL_STEREO_3D_VISION, "NVIDIA 3D Vision Stereo" },
{ NV_CTRL_STEREO_3D_VISION_PRO, "NVIDIA 3D Vision Pro Stereo" },
+ { NV_CTRL_STEREO_HDMI_3D, "HDMI 3D Stereo" },
{ -1, NULL},
};
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index e813baa..034a014 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -819,6 +819,12 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
gtk_tree_store_set(ctk_window->tree_store, &iter,
CTK_WINDOW_CONFIG_FILE_ATTRIBUTES_FUNC_COLUMN,
NULL, -1);
+ gtk_tree_store_set(ctk_window->tree_store, &iter,
+ CTK_WINDOW_SELECT_WIDGET_FUNC_COLUMN,
+ ctk_gpu_page_select, -1);
+ gtk_tree_store_set(ctk_window->tree_store, &iter,
+ CTK_WINDOW_UNSELECT_WIDGET_FUNC_COLUMN,
+ ctk_gpu_page_unselect, -1);
/* power savings */
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index 777f5e4..53bf930 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -197,7 +197,7 @@
/*
- * NV_CTRL_VIDEO_RAM - returns the total amount of memory available
+ * NV_CTRL_TOTAL_GPU_MEMORY - returns the total amount of memory available
* to the specified GPU (or the GPU driving the specified X
* screen). Note: if the GPU supports TurboCache(TM), the value
* reported may exceed the amount of video memory installed on the
@@ -206,7 +206,8 @@
* BIOS for use by the integrated GPU.
*/
-#define NV_CTRL_VIDEO_RAM 6 /* R--G */
+#define NV_CTRL_TOTAL_GPU_MEMORY 6 /* R--G */
+#define NV_CTRL_VIDEO_RAM NV_CTRL_TOTAL_GPU_MEMORY
/*
@@ -3203,7 +3204,22 @@
*/
#define NV_CTRL_DISPLAY_RANDR_OUTPUT_ID 391 /* R-D- */
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DISPLAY_RANDR_OUTPUT_ID
+/*
+ * NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY - Returns the total amount of dedicated
+ * GPU video memory, in MB, on the specified GPU. This excludes any TurboCache
+ * padding included in the value returned by NV_CTRL_TOTAL_GPU_MEMORY.
+ */
+#define NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY 393 /* R--G */
+
+/*
+ * NV_CTRL_USED_DEDICATED_GPU_MEMORY- Returns the amount of video memory
+ * currently used on the graphics card in MB.
+ */
+#define NV_CTRL_USED_DEDICATED_GPU_MEMORY 394 /* R--G */
+
+
+
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_USED_DEDICATED_GPU_MEMORY
/**************************************************************************/
@@ -4235,9 +4251,25 @@
#define NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN 17 /* R--- */
+/*
+ * NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN - Returns the list of
+ * display devices that are currently assigned the X screen target.
+ *
+ * The format of the returned data is:
+ *
+ * 4 CARD32 number of display devices
+ * 4 * n CARD32 display device indices
+ *
+ * This attribute can only be queried through XNVCTRLQueryTargetBinaryData()
+ * using a NV_CTRL_TARGET_TYPE_X_SCREEN target.
+ */
+
+#define NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN 18 /* R--- */
+
+
#define NV_CTRL_BINARY_DATA_LAST_ATTRIBUTE \
- NV_CTRL_BINARY_DATA_DISPLAYS_ENABLED_ON_XSCREEN
+ NV_CTRL_BINARY_DATA_DISPLAYS_ASSIGNED_TO_XSCREEN
/**************************************************************************/
@@ -4428,9 +4460,17 @@
#define NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS 4 /* RW-I */
-#define NV_CTRL_STRING_OPERATION_LAST_ATTRIBUTE \
- NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS
+/*
+ * NV_CTRL_STRING_OPERATION_PARSE_METAMODE - Parses the given MetaMode string
+ * and returns the validated MetaMode string - possibly re-calculating various
+ * values such as ViewPortIn. If the MetaMode matches an existing MetaMode,
+ * the details of the existing MetaMode are returned. If the MetaMode fails to
+ * be parsed, NULL is returned.
+ */
+#define NV_CTRL_STRING_OPERATION_PARSE_METAMODE 5 /* R--- */
+#define NV_CTRL_STRING_OPERATION_LAST_ATTRIBUTE \
+ NV_CTRL_STRING_OPERATION_PARSE_METAMODE
diff --git a/src/parse.c b/src/parse.c
index 1db464f..a27664d 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -143,6 +143,8 @@ AttributeTableEntry attributeTable[] = {
{ "PCIECurrentLinkSpeed", NV_CTRL_GPU_PCIE_CURRENT_LINK_SPEED, N, "Returns the current PCIe link speed, in gigatransfers per second (GT/s)." },
{ "PCIECurrentLinkWidth", NV_CTRL_GPU_PCIE_CURRENT_LINK_WIDTH, N, "Returns the current PCIe link width of the GPU, in number of lanes." },
{ "VideoRam", NV_CTRL_VIDEO_RAM, N, "Returns the total amount of memory available to the specified GPU (or the GPU driving the specified X screen). Note: if the GPU supports TurboCache(TM), the value reported may exceed the amount of video memory installed on the GPU. The value reported for integrated GPUs may likewise exceed the amount of dedicated system memory set aside by the system BIOS for use by the integrated GPU." },
+ { "TotalDedicatedGPUMemory",NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY, N, "Returns the amount of total dedicated memory on the specified GPU in MB." },
+ { "UsedDedicatedGPUMemory", NV_CTRL_USED_DEDICATED_GPU_MEMORY, N, "Returns the amount of dedicated memory used on the specified GPU in MB." },
{ "Irq", NV_CTRL_IRQ, N, "Returns the interrupt request line used by the specified device. If the target is an X screen, then it uses the GPU driving the X screen as the device." },
{ "CUDACores", NV_CTRL_GPU_CORES, N, "Returns number of CUDA cores supported by the graphics pipeline." },
{ "GPUMemoryInterface", NV_CTRL_GPU_MEMORY_BUS_WIDTH, N, "Returns bus bandwidth of the GPU's memory interface." },
@@ -368,7 +370,7 @@ AttributeTableEntry attributeTable[] = {
* about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DISPLAY_RANDR_OUTPUT_ID
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_USED_DEDICATED_GPU_MEMORY
#warning "Have you forgotten to add a new integer attribute to attributeTable?"
#endif
diff --git a/src/version.mk b/src/version.mk
index 1feef56..6db0208 100644
--- a/src/version.mk
+++ b/src/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 310.14
+NVIDIA_VERSION = 310.19
diff --git a/version.mk b/version.mk
index 1feef56..6db0208 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 310.14
+NVIDIA_VERSION = 310.19