summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2012-08-27 10:55:04 -0700
committerAaron Plattner <aplattner@nvidia.com>2012-08-27 10:55:04 -0700
commitcc58d9323aa331f16121c2e157611189cee92293 (patch)
tree69ecfece24b9aece1b200195483d8b91379189c2
parent9adcc9c3cde50ef28b734a036cdc336f70c94597 (diff)
304.43304.43
-rw-r--r--doc/version.mk2
-rw-r--r--samples/version.mk2
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.c43
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.h5
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c105
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.h2
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice.c72
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.c55
-rw-r--r--src/gtk+-2.x/ctkevent.c3
-rw-r--r--src/gtk+-2.x/ctkwindow.c37
-rw-r--r--src/libXNVCtrl/NVCtrl.h10
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.c233
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributes.h15
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h70
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c371
-rw-r--r--src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c269
-rw-r--r--src/parse.c3
-rw-r--r--src/src.mk2
-rw-r--r--src/version.mk2
-rw-r--r--version.mk2
20 files changed, 836 insertions, 467 deletions
diff --git a/doc/version.mk b/doc/version.mk
index c7ccc7a..7753329 100644
--- a/doc/version.mk
+++ b/doc/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 304.37
+NVIDIA_VERSION = 304.43
diff --git a/samples/version.mk b/samples/version.mk
index c7ccc7a..7753329 100644
--- a/samples/version.mk
+++ b/samples/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 304.37
+NVIDIA_VERSION = 304.43
diff --git a/src/gtk+-2.x/ctkcolorcorrection.c b/src/gtk+-2.x/ctkcolorcorrection.c
index a283ddf..9c2fe1f 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.c
+++ b/src/gtk+-2.x/ctkcolorcorrection.c
@@ -25,7 +25,6 @@
#include "red_xpm.h"
#include "green_xpm.h"
#include "blue_xpm.h"
-#include "ctkbanner.h"
#include "ctkcurve.h"
#include "ctkscale.h"
@@ -186,7 +185,6 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
GtkWidget *menu;
GtkWidget *image;
- GtkWidget *banner;
GtkWidget *label;
GtkWidget *scale;
GtkWidget *curve;
@@ -201,20 +199,7 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
GtkWidget *widget;
GtkWidget *hsep;
GtkWidget *eventbox;
- ReturnStatus ret;
- gint val;
- /* check if the VidMode extension is present */
-
- ret = NvCtrlGetAttribute(handle, NV_CTRL_ATTR_EXT_VM_PRESENT, &val);
- if ((ret != NvCtrlSuccess) || (val == FALSE)) return NULL;
-
- /* check if the noScanout mode enabled */
-
- ret = NvCtrlGetAttribute(handle, NV_CTRL_NO_SCANOUT, &val);
- if ((ret == NvCtrlSuccess) && (val == NV_CTRL_NO_SCANOUT_ENABLED))
- return NULL;
-
object = g_object_new(CTK_TYPE_COLOR_CORRECTION, NULL);
ctk_color_correction = CTK_COLOR_CORRECTION(object);
@@ -227,16 +212,6 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
gtk_box_set_spacing(GTK_BOX(ctk_color_correction), 10);
- /*
- * Banner: TOP - LEFT -> RIGHT
- *
- * This image serves as a visual reference for basic color_box correction
- * purposes.
- */
-
- banner = ctk_banner_image_new(BANNER_ARTWORK_COLOR);
- gtk_box_pack_start(GTK_BOX(ctk_color_correction), banner, FALSE, FALSE, 0);
-
/* create the main hbox and the two main vboxes*/
mainhbox = gtk_hbox_new(FALSE, 10);
@@ -1039,7 +1014,9 @@ static gboolean do_confirm_countdown(gpointer data)
} /* do_confirm_countdown() */
-GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table)
+GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table,
+ const gchar *title,
+ gboolean randr)
{
GtkTextIter i;
GtkTextBuffer *b;
@@ -1048,7 +1025,7 @@ GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table)
gtk_text_buffer_get_iter_at_offset(b, &i, 0);
- ctk_help_title(b, &i, "X Server Color Correction Help");
+ ctk_help_title(b, &i, "%s Help", title);
ctk_help_heading(b, &i, "Active Color Channel");
ctk_help_para(b, &i, __active_color_help);
@@ -1072,10 +1049,14 @@ GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table)
ctk_help_para(b, &i, __color_curve_help);
- ctk_help_para(b, &i, "Note that the X Server Color Correction page uses "
- "the XF86VidMode extension to manipulate the X screen's "
- "color ramps.");
-
+ if (randr) {
+ 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 "
+ "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);
diff --git a/src/gtk+-2.x/ctkcolorcorrection.h b/src/gtk+-2.x/ctkcolorcorrection.h
index 5bbc251..53cb36e 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.h
+++ b/src/gtk+-2.x/ctkcolorcorrection.h
@@ -79,8 +79,9 @@ GType ctk_color_correction_get_type (void) G_GNUC_CONST;
GtkWidget* ctk_color_correction_new (NvCtrlAttributeHandle *,
CtkConfig *, ParsedAttribute *,
CtkEvent *);
-GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *);
-
+GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *,
+ const gchar *title,
+ gboolean randr);
G_END_DECLS
#endif /* __CTK_COLOR_CORRECTION_H__ */
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 813aef8..9cb4e93 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -1807,6 +1807,18 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(ctk_object), vbox, FALSE, FALSE, 0);
ctk_object->screen_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 = hbox;
+
/* X screen virtual size */
label = gtk_label_new("Virtual Size:");
labels = g_slist_append(labels, label);
@@ -2011,7 +2023,10 @@ GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *table,
"that display devices and X screens have to each other. "
"You may drag display devices around to reposition them. "
"When in advanced view, the display's panning domain may "
- "be resized by holding shift while dragging.");
+ "be resized by holding SHIFT while dragging. Also, The "
+ "X screen a display belongs to may be selected by holding "
+ "down the CONTROL key while clicking on the display, and can "
+ "be moved by holding CONTROL-Click and dragging.");
ctk_help_heading(b, &i, "Layout Hidden Label");
ctk_help_para(b, &i, __layout_hidden_label_help);
ctk_help_heading(b, &i, "Enable Xinerama");
@@ -3752,6 +3767,12 @@ static void setup_screen_page(CtkDisplayConfig *ctk_object)
/* Enable display widgets and setup widget information */
gtk_widget_set_sensitive(ctk_object->screen_page, True);
+ if (screen->layout->num_screens > 1) {
+ gtk_widget_show(ctk_object->box_screen_drag_info);
+ } else {
+ gtk_widget_hide(ctk_object->box_screen_drag_info);
+ }
+
setup_screen_virtual_size(ctk_object);
setup_screen_depth_dropdown(ctk_object);
setup_screen_stereo_dropdown(ctk_object);
@@ -3765,8 +3786,8 @@ static void setup_screen_page(CtkDisplayConfig *ctk_object)
/** validation_fix_crowded_metamodes() *******************************
*
* Goes through each screen's metamodes and ensures that at most
- * two display devices are active (have a modeline set) per metamode.
- * This function also checks to make sure that there is at least
+ * (max supported) display devices are active (have a modeline set) per
+ * metamode. This function also checks to make sure that there is at least
* one display device active for each metamode.
*
**/
@@ -3872,54 +3893,6 @@ static gint validation_fix_crowded_metamodes(CtkDisplayConfig *ctk_object,
-/** validation_fix_crowded_metamodes() *******************************
- *
- * Goes through each screen's metamodes and ensures that each
- * metamode string is unique. If a metamode string is not unique,
- * the duplicate metamode is removed.
- *
- **/
-
-static gint validation_remove_dupe_metamodes(CtkDisplayConfig *ctk_object,
- nvScreenPtr screen)
-{
- int i, j;
- char *metamode_str;
-
- /* Verify each metamode with the metamodes that come before it */
- for (i = 1; i < screen->num_metamodes; i++) {
-
- metamode_str = screen_get_metamode_str(screen, i, 0);
- for (j = 0; j < i; j++) {
- char *tmp;
- tmp = screen_get_metamode_str(screen, j, 0);
-
- /* Remove duplicates */
- if (!strcmp(metamode_str, tmp)) {
-
- /* Delete the metamode */
- ctk_display_layout_delete_screen_metamode
- (CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), screen, i,
- TRUE);
-
- nv_info_msg(TAB, "Removed MetaMode %d on Screen %d (Is "
- "Duplicate of MetaMode %d)\n", i+1, screen->scrnum,
- j+1);
- g_free(tmp);
- i--; /* Check the new metamode in i'th position */
- break;
- }
- g_free(tmp);
- }
- g_free(metamode_str);
- }
-
- return 1;
-
-} /* validation_remove_dupe_metamodes() */
-
-
-
/** validation_auto_fix_screen() *************************************
*
* Do what we can to make this screen conform to validation.
@@ -3932,7 +3905,6 @@ static gint validation_auto_fix_screen(CtkDisplayConfig *ctk_object,
gint status = 1;
status &= validation_fix_crowded_metamodes(ctk_object, screen);
- status &= validation_remove_dupe_metamodes(ctk_object, screen);
return status;
@@ -3988,9 +3960,8 @@ static gint validation_auto_fix(CtkDisplayConfig *ctk_object)
*
* - Have at least 1 display device activated for all metamodes.
*
- * - Have at most 2 display devices activated for all metamodes.
- *
- * - All metamodes must be unique.
+ * - Have at most (max supported) display devices activated for all
+ * metamodes.
*
* - All metamodes must have a coherent offset (The top left corner
* of the bounding box of all the metamodes must be the same.)
@@ -4007,7 +3978,6 @@ static gchar * validate_screen(nvScreenPtr screen)
nvModePtr mode;
int i, j;
int num_displays;
- char *metamode_str;
gchar *err_str = NULL;
gchar *tmp;
gchar *tmp2;
@@ -4063,29 +4033,6 @@ static gchar * validate_screen(nvScreenPtr screen)
g_free(tmp);
err_str = tmp2;
}
-
-
- /* Verify that the metamode is unique */
- metamode_str = screen_get_metamode_str(screen, i, 0);
- for (j = 0; j < i; j++) {
- char *tmp = screen_get_metamode_str(screen, j, 0);
-
- /* Make sure the metamode is unique */
- if (!strcmp(metamode_str, tmp)) {
- g_free(tmp);
- tmp = g_strdup_printf("%s MetaMode %d of Screen %d is the "
- "same as MetaMode %d. All MetaModes "
- "must be unique.\n\n",
- bullet, i+1, screen->scrnum, j+1);
- tmp2 = g_strconcat((err_str ? err_str : ""), tmp, NULL);
- g_free(err_str);
- err_str = tmp2;
- g_free(tmp);
- break;
- }
- g_free(tmp);
- }
- g_free(metamode_str);
}
return err_str;
diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h
index 7e415e8..c90c0d5 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.h
+++ b/src/gtk+-2.x/ctkdisplayconfig.h
@@ -130,6 +130,8 @@ typedef struct _CtkDisplayConfig
GtkWidget *screen_page;
/* X Screen - Settings */
+ GtkWidget *box_screen_drag_info;
+
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 b74dfb2..3a7e2fa 100644
--- a/src/gtk+-2.x/ctkdisplaydevice.c
+++ b/src/gtk+-2.x/ctkdisplaydevice.c
@@ -33,6 +33,7 @@
#include "ctkcolorcontrols.h"
#include "ctkimagesliders.h"
#include "ctkedid.h"
+#include "ctkcolorcorrection.h"
#include "ctkconfig.h"
#include "ctkhelp.h"
#include "ctkutils.h"
@@ -66,6 +67,10 @@ static void unregister_link_events(InfoEntry *entry);
static void register_refresh_rate_events(InfoEntry *entry);
static void unregister_refresh_rate_events(InfoEntry *entry);
+static void add_color_correction_tab(CtkDisplayDevice *ctk_object,
+ CtkConfig *ctk_config,
+ CtkEvent *ctk_event,
+ GtkWidget *notebook);
#define FRAME_PADDING 5
@@ -253,19 +258,6 @@ GtkWidget* ctk_display_device_new(NvCtrlAttributeHandle *handle,
}
gtk_box_pack_start(GTK_BOX(object), banner, FALSE, FALSE, 0);
- /* Reset button */
-
- button = gtk_button_new_with_label("Reset Hardware Defaults");
- str = ctk_help_create_reset_hardware_defaults_text(typeBaseName,
- name);
- ctk_config_set_tooltip(ctk_config, button, str);
- ctk_object->reset_button = button;
-
- alignment = gtk_alignment_new(1, 1, 0, 0);
- gtk_container_add(GTK_CONTAINER(alignment), button);
- gtk_box_pack_end(GTK_BOX(object), alignment, FALSE, FALSE, 0);
-
-
/* Create tabbed notebook for widget */
notebook = gtk_notebook_new();
@@ -400,6 +392,18 @@ GtkWidget* ctk_display_device_new(NvCtrlAttributeHandle *handle,
FALSE, FALSE, 0);
}
+ /* pack the reset button */
+
+ button = gtk_button_new_with_label("Reset Hardware Defaults");
+ str = ctk_help_create_reset_hardware_defaults_text(typeBaseName,
+ name);
+ ctk_config_set_tooltip(ctk_config, button, str);
+ ctk_object->reset_button = button;
+
+ alignment = gtk_alignment_new(1, 1, 0, 0);
+ gtk_container_add(GTK_CONTAINER(alignment), button);
+ gtk_box_pack_end(GTK_BOX(nbox), alignment, FALSE, FALSE, 0);
+
/* If no controls are created, don't add a controls tab */
if (ctk_object->color_controls ||
@@ -409,6 +413,10 @@ GtkWidget* ctk_display_device_new(NvCtrlAttributeHandle *handle,
gtk_label_new("Controls"));
}
+ /* add the color correction tab if RandR is available */
+
+ add_color_correction_tab(ctk_object, ctk_config, ctk_event, notebook);
+
/* Update the GUI */
gtk_widget_show_all(GTK_WIDGET(object));
@@ -851,3 +859,41 @@ static void callback_refresh_rate_changed(GtkObject *object, gpointer arg1,
update_refresh_rate(entry);
}
+
+
+static void add_color_correction_tab(CtkDisplayDevice *ctk_object,
+ CtkConfig *ctk_config,
+ CtkEvent *ctk_event,
+ GtkWidget *notebook)
+{
+ ReturnStatus ret;
+ gint val;
+ GtkWidget *ctk_color_correction;
+ GtkWidget *box;
+
+ ret = NvCtrlGetAttribute(ctk_object->handle,
+ NV_CTRL_ATTR_RANDR_GAMMA_AVAILABLE, &val);
+
+ if (ret != NvCtrlSuccess) {
+ return;
+ }
+
+ if (val != 1) {
+ return;
+ }
+
+ ctk_color_correction = ctk_color_correction_new(ctk_object->handle,
+ ctk_config,
+ NULL /* ParsedAttribute*/,
+ ctk_event);
+ if (ctk_color_correction == NULL) {
+ return;
+ }
+
+ box = gtk_hbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(box), FRAME_PADDING);
+ gtk_box_pack_start(GTK_BOX(box), ctk_color_correction, TRUE, TRUE, 0);
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), box,
+ gtk_label_new("Color Correction"));
+}
diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c
index f2a18ec..7226ae8 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.c
+++ b/src/gtk+-2.x/ctkdisplaylayout.c
@@ -30,6 +30,7 @@
#include "ctkhelp.h"
#include "ctkdisplaylayout.h"
#include "ctkdisplayconfig-utils.h"
+#include "ctkutils.h"
@@ -455,11 +456,12 @@ static Bool get_modify_info(CtkDisplayLayout *ctk_object)
*
**/
-static void sync_scaling(CtkDisplayLayout *ctk_object)
+static Bool sync_scaling(CtkDisplayLayout *ctk_object)
{
int *dim = ctk_object->layout->dim;
float wscale;
float hscale;
+ float prev_scale = ctk_object->scale;
wscale = (float)(ctk_object->img_dim[W]) / (float)(dim[W]);
hscale = (float)(ctk_object->img_dim[H]) / (float)(dim[H]);
@@ -470,6 +472,8 @@ static void sync_scaling(CtkDisplayLayout *ctk_object)
ctk_object->scale = wscale;
}
+ return (prev_scale != ctk_object->scale);
+
} /* sync_scaling() */
@@ -1116,7 +1120,7 @@ static void recenter_screen(nvScreenPtr screen)
*
**/
-static void set_screen_metamode(nvLayoutPtr layout, nvScreenPtr screen,
+static Bool set_screen_metamode(nvLayoutPtr layout, nvScreenPtr screen,
int new_metamode_idx)
{
nvDisplayPtr display;
@@ -1135,7 +1139,12 @@ static void set_screen_metamode(nvLayoutPtr layout, nvScreenPtr screen,
/* Recalculate the layout dimensions */
calc_layout(layout);
- offset_layout(layout, -layout->dim[X], -layout->dim[Y]);
+ if (layout->dim[X] || layout->dim[Y]) {
+ offset_layout(layout, -layout->dim[X], -layout->dim[Y]);
+ return TRUE;
+ }
+
+ return FALSE;
} /* set_screen_metamode() */
@@ -1149,11 +1158,12 @@ static void set_screen_metamode(nvLayoutPtr layout, nvScreenPtr screen,
*
**/
-static void recenter_layout(nvLayoutPtr layout)
+static Bool recenter_layout(nvLayoutPtr layout)
{
nvScreenPtr screen;
int real_metamode_idx;
int metamode_idx;
+ Bool modified = FALSE;
for (screen = layout->screens; screen; screen = screen->next_in_layout) {
@@ -1165,12 +1175,18 @@ static void recenter_layout(nvLayoutPtr layout)
if (metamode_idx == real_metamode_idx) continue;
- set_screen_metamode(layout, screen, metamode_idx);
+ if (set_screen_metamode(layout, screen, metamode_idx)) {
+ modified = TRUE;
+ }
}
- set_screen_metamode(layout, screen, real_metamode_idx);
+ if (set_screen_metamode(layout, screen, real_metamode_idx)) {
+ modified = TRUE;
+ }
}
+ return modified;
+
} /* recenter_layout() */
@@ -2015,8 +2031,12 @@ static int move_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
modified = 1;
}
- recenter_layout(layout);
- sync_scaling(ctk_object);
+ if (recenter_layout(layout)) {
+ modified = 1;
+ }
+ if (sync_scaling(ctk_object)) {
+ modified = 1;
+ }
/* If what we moved required the layout to be shifted, offset
@@ -2174,9 +2194,12 @@ static int pan_selected(CtkDisplayLayout *ctk_object, int x, int y, int snap)
modified = 1;
}
- recenter_layout(layout);
- sync_scaling(ctk_object);
-
+ if (recenter_layout(layout)) {
+ modified = 1;
+ }
+ if (sync_scaling(ctk_object)) {
+ modified = 1;
+ }
/* Check if the item being moved has a new position */
/* Report if anything changed */
@@ -2613,6 +2636,7 @@ static int click_layout(CtkDisplayLayout *ctk_object, int x, int y)
nvDisplayPtr display;
nvScreenPtr screen;
int *sdim;
+ GdkModifierType state;
/* Assume user didn't actually click inside a display for now */
@@ -2620,6 +2644,9 @@ static int click_layout(CtkDisplayLayout *ctk_object, int x, int y)
ctk_object->selected_display = NULL;
ctk_object->selected_screen = NULL;
+ gdk_window_get_pointer
+ (GTK_WIDGET(ctk_get_parent_window(ctk_object->drawing_area))->window,
+ NULL, NULL, &state);
/* Look through the Z-order for the next element */
for (i = 0; i < ctk_object->Zcount; i++) {
@@ -2643,6 +2670,10 @@ static int click_layout(CtkDisplayLayout *ctk_object, int x, int y)
}
}
+ /* Select display's X screen when CTRL is held down on click */
+ if (ctk_object->selected_screen && (state & GDK_CONTROL_MASK)) {
+ ctk_object->selected_display = NULL;
+ }
/* Don't allow clicking outside - reselect what was last selected */
if (ctk_object->clicked_outside) {
@@ -4264,7 +4295,7 @@ motion_event_callback(GtkWidget *widget, GdkEventMotion *event, gpointer data)
}
/* Swap between panning and moving */
- if (ctk_object->advanced_mode && (state & ShiftMask)) {
+ if (ctk_object->advanced_mode && (state & GDK_SHIFT_MASK)) {
modify_panning = 1;
} else {
modify_panning = 0;
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index e6aaa0c..115b119 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -329,6 +329,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_DISPLAY_ENABLED);
MAKE_SIGNAL(NV_CTRL_FRAMELOCK_INCOMING_HOUSE_SYNC_RATE);
MAKE_SIGNAL(NV_CTRL_FXAA);
+ MAKE_SIGNAL(NV_CTRL_DISPLAY_RANDR_OUTPUT_ID);
#undef MAKE_SIGNAL
/*
@@ -338,7 +339,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_FXAA
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DISPLAY_RANDR_OUTPUT_ID
#warning "There are attributes that do not emit signals!"
#endif
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index 0919bf1..dee4e6a 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -44,6 +44,7 @@
#include "ctkslimm.h"
#include "ctkgpu.h"
#include "ctkcolorcorrection.h"
+#include "ctkcolorcorrectionpage.h"
#include "ctkxvideo.h"
#include "ctkcursorshadow.h"
#include "ctkopengl.h"
@@ -382,6 +383,16 @@ static gboolean tree_view_key_event(GtkWidget *tree_view, GdkEvent *event,
} /* tree_view_key_event() */
+static gboolean has_randr_gamma(NvCtrlAttributeHandle *handle)
+{
+ ReturnStatus ret;
+ int val;
+
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_ATTR_RANDR_GAMMA_AVAILABLE, &val);
+
+ return ((ret == NvCtrlSuccess) && (val == 1));
+}
+
/*
* ctk_window_new() - create a new CtkWindow widget
*/
@@ -666,15 +677,22 @@ GtkWidget *ctk_window_new(ParsedAttribute *p, ConfigProperties *conf,
}
}
- /* color correction */
+ /*
+ * color correction, if RandR per-CRTC color correction is not
+ * available
+ */
+
+ if (!has_randr_gamma(screen_handle)) {
- child = ctk_color_correction_new(screen_handle, ctk_config,
- ctk_window->attribute_list,
- ctk_event);
- if (child) {
- help = ctk_color_correction_create_help(tag_table);
- add_page(child, help, ctk_window, &iter, NULL,
- "X Server Color Correction", NULL, NULL, NULL);
+ child = ctk_color_correction_page_new(screen_handle, ctk_config,
+ ctk_window->attribute_list,
+ ctk_event);
+ if (child) {
+ const char *title = "X Server Color Correction";
+ help = ctk_color_correction_page_create_help(tag_table, title);
+ add_page(child, help, ctk_window, &iter, NULL,
+ title, NULL, NULL, NULL);
+ }
}
/* xvideo settings */
@@ -1396,7 +1414,8 @@ static void add_display_devices(CtkWindow *ctk_window, GtkTreeIter *iter,
NvCtrlAttributeInit(NvCtrlGetDisplayPtr(gpu_handle),
NV_CTRL_TARGET_TYPE_DISPLAY,
display_id,
- NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM);
+ NV_CTRL_ATTRIBUTES_NV_CONTROL_SUBSYSTEM |
+ NV_CTRL_ATTRIBUTES_XRANDR_SUBSYSTEM);
if (!display_handle) {
continue;
}
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index 2b05050..98b8fda 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -3203,9 +3203,15 @@
#define NV_CTRL_FXAA_DISABLE 0
#define NV_CTRL_FXAA_ENABLE 1
+/*
+ * NV_CTRL_DISPLAY_RANDR_OUTPUT_ID - the RandR Output ID (type RROutput)
+ * that corresponds to the specified Display Device target. If a new
+ * enough version of RandR is not available in the X server,
+ * DISPLAY_RANDR_OUTPUT_ID will be 0.
+ */
+#define NV_CTRL_DISPLAY_RANDR_OUTPUT_ID 391 /* R-D- */
-
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_FXAA
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DISPLAY_RANDR_OUTPUT_ID
/**************************************************************************/
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.c b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
index 1c2a78b..150126d 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.c
@@ -2,7 +2,7 @@
* nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
* and Linux systems.
*
- * Copyright (C) 2004 NVIDIA Corporation.
+ * Copyright (C) 2004,2012 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <math.h> /* pow(3) */
#include <sys/utsname.h>
@@ -96,18 +97,16 @@ NvCtrlAttributeHandle *NvCtrlAttributeInit(Display *dpy, int target_type,
if (subsystems & NV_CTRL_ATTRIBUTES_GLX_SUBSYSTEM) {
h->glx = NvCtrlInitGlxAttributes(h);
}
-
- /*
- * initialize the XRandR extension and attributes; it is OK if
- * this fails
- */
-
- if (subsystems & NV_CTRL_ATTRIBUTES_XRANDR_SUBSYSTEM) {
- h->xrandr = NvCtrlInitXrandrAttributes(h);
- }
-
} /* X Screen target type attribute subsystems */
-
+
+ /*
+ * initialize the XRandR extension and attributes; this does not
+ * require an X screen and it is OK if this fails
+ */
+ if (subsystems & NV_CTRL_ATTRIBUTES_XRANDR_SUBSYSTEM) {
+ h->xrandr = NvCtrlInitXrandrAttributes(h);
+ }
+
return (NvCtrlAttributeHandle *) h;
failed:
@@ -551,7 +550,12 @@ NvCtrlGetDisplayAttribute64(NvCtrlAttributeHandle *handle,
}
return NvCtrlSuccess;
}
-
+
+ if (attr >= NV_CTRL_ATTR_RANDR_BASE &&
+ attr <= NV_CTRL_ATTR_RANDR_LAST_ATTRIBUTE) {
+ return NvCtrlXrandrGetAttribute(h, display_mask, attr, val);
+ }
+
if (((attr >= 0) && (attr <= NV_CTRL_LAST_ATTRIBUTE)) ||
((attr >= NV_CTRL_ATTR_NV_BASE) &&
(attr <= NV_CTRL_ATTR_NV_LAST_ATTRIBUTE))) {
@@ -930,3 +934,206 @@ const char *NvCtrlGetMultisampleModeName(int multisample_mode)
return mode_names[multisample_mode];
} /* NvCtrlGetMultisampleModeName */
+
+
+ReturnStatus NvCtrlGetColorAttributes(NvCtrlAttributeHandle *handle,
+ float contrast[3],
+ float brightness[3],
+ float gamma[3])
+{
+ NvCtrlAttributePrivateHandle *h = (NvCtrlAttributePrivateHandle *) handle;
+
+ if (h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) {
+ return NvCtrlVidModeGetColorAttributes(h, contrast, brightness, gamma);
+ } else if (h->target_type == NV_CTRL_TARGET_TYPE_DISPLAY) {
+ return NvCtrlXrandrGetColorAttributes(h, contrast, brightness, gamma);
+ }
+
+ return NvCtrlBadHandle;
+}
+
+ReturnStatus NvCtrlSetColorAttributes(NvCtrlAttributeHandle *handle,
+ float c[3],
+ float b[3],
+ float g[3],
+ unsigned int bitmask)
+{
+ NvCtrlAttributePrivateHandle *h = (NvCtrlAttributePrivateHandle *) handle;
+
+ if (h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) {
+ return NvCtrlVidModeSetColorAttributes(h, c, b, g, bitmask);
+ } else if (h->target_type == NV_CTRL_TARGET_TYPE_DISPLAY) {
+ return NvCtrlXrandrSetColorAttributes(h, c, b, g, bitmask);
+ }
+
+ return NvCtrlBadHandle;
+}
+
+
+ReturnStatus NvCtrlGetColorRamp(NvCtrlAttributeHandle *handle,
+ unsigned int channel,
+ uint16_t **lut,
+ int *n)
+{
+ NvCtrlAttributePrivateHandle *h = (NvCtrlAttributePrivateHandle *) handle;
+
+ if (h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) {
+ return NvCtrlVidModeGetColorRamp(h, channel, lut, n);
+ } else if (h->target_type == NV_CTRL_TARGET_TYPE_DISPLAY) {
+ return NvCtrlXrandrGetColorRamp(h, channel, lut, n);
+ }
+
+ return NvCtrlBadHandle;
+}
+
+
+/* helper functions private to the libXNVCtrlAttributes backend */
+
+void NvCtrlInitGammaInputStruct(NvCtrlGammaInput *pGammaInput)
+{
+ int ch;
+
+ for (ch = FIRST_COLOR_CHANNEL; ch <= LAST_COLOR_CHANNEL; ch++) {
+ pGammaInput->brightness[ch] = BRIGHTNESS_DEFAULT;
+ pGammaInput->contrast[ch] = CONTRAST_DEFAULT;
+ pGammaInput->gamma[ch] = GAMMA_DEFAULT;
+ }
+}
+
+/*
+ * Compute the gammaRamp entry given its index, and the contrast,
+ * brightness, and gamma.
+ */
+static unsigned short ComputeGammaRampVal(int gammaRampSize,
+ int i,
+ float contrast,
+ float brightness,
+ float gamma)
+{
+ double j, half, scale;
+ int shift, val, num;
+
+ num = gammaRampSize - 1;
+ shift = 16 - (ffs(gammaRampSize) - 1);
+
+ scale = (double) num / 3.0; /* how much brightness and contrast
+ affect the value */
+ j = (double) i;
+
+ /* contrast */
+
+ contrast *= scale;
+
+ if (contrast > 0.0) {
+ half = ((double) num / 2.0) - 1.0;
+ j -= half;
+ j *= half / (half - contrast);
+ j += half;
+ } else {
+ half = (double) num / 2.0;
+ j -= half;
+ j *= (half + contrast) / half;
+ j += half;
+ }
+
+ if (j < 0.0) j = 0.0;
+
+ /* gamma */
+
+ gamma = 1.0 / (double) gamma;
+
+ if (gamma == 1.0) {
+ val = (int) j;
+ } else {
+ val = (int) (pow (j / (double)num, gamma) * (double)num + 0.5);
+ }
+
+ /* brightness */
+
+ brightness *= scale;
+
+ val += (int)brightness;
+ if (val > num) val = num;
+ if (val < 0) val = 0;
+
+ val <<= shift;
+ return (unsigned short) val;
+}
+
+void NvCtrlUpdateGammaRamp(const NvCtrlGammaInput *pGammaInput,
+ int gammaRampSize,
+ unsigned short *gammaRamp[3],
+ unsigned int bitmask)
+{
+ int i, ch;
+
+ /* update the requested channels within the gammaRamp */
+
+ for (ch = FIRST_COLOR_CHANNEL; ch <= LAST_COLOR_CHANNEL; ch++) {
+
+ /* only update requested channels */
+
+ if ((bitmask & (1 << ch)) == 0) {
+ continue;
+ }
+
+ for (i = 0; i < gammaRampSize; i++) {
+ gammaRamp[ch][i] =
+ ComputeGammaRampVal(gammaRampSize,
+ i,
+ pGammaInput->contrast[ch],
+ pGammaInput->brightness[ch],
+ pGammaInput->gamma[ch]);
+ }
+ }
+}
+
+void NvCtrlAssignGammaInput(NvCtrlGammaInput *pGammaInput,
+ const float inContrast[3],
+ const float inBrightness[3],
+ const float inGamma[3],
+ const unsigned int bitmask)
+{
+ int ch;
+
+ /* clamp input, but only the input specified in the bitmask */
+
+ for (ch = FIRST_COLOR_CHANNEL; ch <= LAST_COLOR_CHANNEL; ch++) {
+
+ /* only update requested channels */
+
+ if ((bitmask & (1 << ch)) == 0) {
+ continue;
+ }
+
+ if (bitmask & CONTRAST_VALUE) {
+ if (inContrast[ch] > CONTRAST_MAX) {
+ pGammaInput->contrast[ch] = CONTRAST_MAX;
+ } else if (inContrast[ch] < CONTRAST_MIN) {
+ pGammaInput->contrast[ch] = CONTRAST_MIN;
+ } else {
+ pGammaInput->contrast[ch] = inContrast[ch];
+ }
+ }
+
+ if (bitmask & BRIGHTNESS_VALUE) {
+ if (inBrightness[ch] > BRIGHTNESS_MAX) {
+ pGammaInput->brightness[ch] = BRIGHTNESS_MAX;
+ } else if (inBrightness[ch] < BRIGHTNESS_MIN) {
+ pGammaInput->brightness[ch] = BRIGHTNESS_MIN;
+ } else {
+ pGammaInput->brightness[ch] = inBrightness[ch];
+ }
+ }
+
+ if (bitmask & GAMMA_VALUE) {
+ if (inGamma[ch] > GAMMA_MAX) {
+ pGammaInput->gamma[ch] = GAMMA_MAX;
+ } else if (inGamma[ch] < GAMMA_MIN) {
+ pGammaInput->gamma[ch] = GAMMA_MIN;
+ } else {
+ pGammaInput->gamma[ch] = inGamma[ch];
+ }
+ }
+ }
+}
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributes.h b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
index 8da3aa5..bfb51d2 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributes.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributes.h
@@ -43,6 +43,9 @@ typedef void NvCtrlAttributeHandle;
#define GREEN_CHANNEL_INDEX 1
#define BLUE_CHANNEL_INDEX 2
+#define FIRST_COLOR_CHANNEL RED_CHANNEL_INDEX
+#define LAST_COLOR_CHANNEL BLUE_CHANNEL_INDEX
+
#define CONTRAST_INDEX 3
#define BRIGHTNESS_INDEX 4
#define GAMMA_INDEX 5
@@ -106,7 +109,17 @@ typedef void NvCtrlAttributeHandle;
#define NV_CTRL_ATTR_GLX_LAST_ATTRIBUTE \
(NV_CTRL_ATTR_GLX_FBCONFIG_ATTRIBS)
-#define NV_CTRL_ATTR_LAST_ATTRIBUTE (NV_CTRL_ATTR_GLX_LAST_ATTRIBUTE)
+/* RandR */
+
+#define NV_CTRL_ATTR_RANDR_BASE \
+ (NV_CTRL_ATTR_GLX_LAST_ATTRIBUTE + 1)
+
+#define NV_CTRL_ATTR_RANDR_GAMMA_AVAILABLE (NV_CTRL_ATTR_RANDR_BASE + 0)
+
+#define NV_CTRL_ATTR_RANDR_LAST_ATTRIBUTE \
+ (NV_CTRL_ATTR_RANDR_GAMMA_AVAILABLE)
+
+#define NV_CTRL_ATTR_LAST_ATTRIBUTE (NV_CTRL_ATTR_RANDR_LAST_ATTRIBUTE)
typedef enum {
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
index 5daa455..36cbcb9 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesPrivate.h
@@ -2,7 +2,7 @@
* nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
* and Linux systems.
*
- * Copyright (C) 2004 NVIDIA Corporation.
+ * Copyright (C) 2004,2012 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -23,6 +23,7 @@
#include "NvCtrlAttributes.h"
#include "NVCtrl.h"
#include <GL/glx.h> /* GLX #defines */
+#include <X11/extensions/Xrandr.h> /* Xrandr */
#define EXTENSION_NV_CONTROL 0x1
@@ -80,6 +81,12 @@ typedef struct __NvCtrlXvBlitterAttributes NvCtrlXvBlitterAttributes;
typedef struct __NvCtrlXvAttribute NvCtrlXvAttribute;
typedef struct __NvCtrlXrandrAttributes NvCtrlXrandrAttributes;
+typedef struct {
+ float brightness[3];
+ float contrast[3];
+ float gamma[3];
+} NvCtrlGammaInput;
+
struct __NvCtrlNvControlAttributes {
int event_base;
int error_base;
@@ -88,14 +95,11 @@ struct __NvCtrlNvControlAttributes {
};
struct __NvCtrlVidModeAttributes {
- int n;
- int sigbits;
int major_version;
int minor_version;
unsigned short *lut[3];
- float brightness[3];
- float contrast[3];
- float gamma[3];
+ int gammaRampSize;
+ NvCtrlGammaInput gammaInput;
};
struct __NvCtrlXvAttributes {
@@ -111,6 +115,10 @@ struct __NvCtrlXrandrAttributes {
int error_base;
int major_version;
int minor_version;
+ Bool gammaAvailable;
+ RRCrtc gammaCrtc;
+ NvCtrlGammaInput gammaInput;
+ XRRCrtcGamma *pGammaRamp;
};
struct __NvCtrlAttributePrivateHandle {
@@ -177,12 +185,47 @@ NvCtrlXrandrGetStringAttribute (NvCtrlAttributePrivateHandle *,
unsigned int, int, char **);
+ReturnStatus NvCtrlXrandrGetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float contrast[3],
+ float brightness[3],
+ float gamma[3]);
+
+ReturnStatus NvCtrlXrandrSetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float c[3],
+ float b[3],
+ float g[3],
+ unsigned int bitmask);
+
+ReturnStatus NvCtrlXrandrGetColorRamp(NvCtrlAttributePrivateHandle *h,
+ unsigned int channel,
+ uint16_t **lut,
+ int *n);
+
/* XF86 Video Mode extension attribute functions */
+ReturnStatus NvCtrlVidModeGetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float contrast[3],
+ float brightness[3],
+ float gamma[3]);
+
+ReturnStatus NvCtrlVidModeSetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float c[3],
+ float b[3],
+ float g[3],
+ unsigned int bitmask);
+
+ReturnStatus NvCtrlVidModeGetColorRamp(NvCtrlAttributePrivateHandle *h,
+ unsigned int channel,
+ uint16_t **lut,
+ int *n);
+
ReturnStatus
NvCtrlVidModeGetStringAttribute (NvCtrlAttributePrivateHandle *,
unsigned int, int, char **);
+ReturnStatus
+NvCtrlXrandrGetAttribute(NvCtrlAttributePrivateHandle *h,
+ unsigned int display_mask, int attr, int64_t *val);
/* Generic attribute functions */
@@ -230,4 +273,19 @@ NvCtrlNvControlStringOperation (NvCtrlAttributePrivateHandle *h,
unsigned int display_mask, int attr,
char *ptrIn, char **ptrOut);
+/* helper functions for XV86VidMode and RandR backends */
+
+void NvCtrlInitGammaInputStruct(NvCtrlGammaInput *pGammaInput);
+
+void NvCtrlUpdateGammaRamp(const NvCtrlGammaInput *pGammaInput,
+ int gammaRampSize,
+ unsigned short *gammaRamp[3],
+ unsigned int bitmask);
+
+void NvCtrlAssignGammaInput(NvCtrlGammaInput *pGammaInput,
+ const float inContrast[3],
+ const float inBrightness[3],
+ const float inGamma[3],
+ const unsigned int bitmask);
+
#endif /* __NVCTRL_ATTRIBUTES_PRIVATE__ */
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c b/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c
index 013b9ab..f16db84 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesVidMode.c
@@ -2,7 +2,7 @@
* nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
* and Linux systems.
*
- * Copyright (C) 2004 NVIDIA Corporation.
+ * Copyright (C) 2004,2012 NVIDIA Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,176 +26,84 @@
#include <stdlib.h>
#include <string.h>
-#include <math.h>
-
-static unsigned short computeVal(NvCtrlAttributePrivateHandle *,
- int, float, float, float);
-
-#define RED RED_CHANNEL_INDEX
-#define GREEN GREEN_CHANNEL_INDEX
-#define BLUE BLUE_CHANNEL_INDEX
-
-
-/*
- * XXX The XF86VidMode extension can block remote clients.
- * Unfortunately, there doesn't seem to be a good way to determine if
- * we're blocked or not. So, we temporarily plug in an error handler,
- * and watch for the XF86VidModeClientNotLocal error code, set a flag
- * indicating that we should not use the XF86VidMode extension, and
- * then restore the previous error handler. Yuck.
- *
- * XXX Different versions of XFree86 trigger errors on different
- * protocol; older versions trigger an error on
- * XF86VidModeGetGammaRampSize(), but newer versions appear to only
- * error on XF86VidModeSetGammaRamp().
- */
-
-static Bool vidModeBlocked = False;
-static int vidModeErrorBase = 0;
-static int (*prev_error_handler)(Display *, XErrorEvent *) = NULL;
-
-static int vidModeErrorHandler(Display *dpy, XErrorEvent *err)
-{
- if (err->error_code == (XF86VidModeClientNotLocal + vidModeErrorBase)) {
- vidModeBlocked = True;
- } else {
- if (prev_error_handler) prev_error_handler(dpy, err);
- }
-
- return 1;
-}
-
NvCtrlVidModeAttributes *
NvCtrlInitVidModeAttributes(NvCtrlAttributePrivateHandle *h)
{
NvCtrlVidModeAttributes *vm = NULL;
- int ret, event, i;
-
+ int event, error, size, permissions = 0;
+ Bool ret;
/* Check parameters */
if (!h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN) {
goto failed;
}
- ret = XF86VidModeQueryExtension(h->dpy, &event, &vidModeErrorBase);
- if (ret != True) goto failed;
+ ret = XF86VidModeQueryExtension(h->dpy, &event, &error);
+ if (!ret) goto failed;
- vm = malloc(sizeof(NvCtrlVidModeAttributes));
+ vm = calloc(1, sizeof(NvCtrlVidModeAttributes));
ret = XF86VidModeQueryVersion(h->dpy, &(vm->major_version), &(vm->minor_version));
- if (ret != True) goto failed;
+ if (!ret) goto failed;
- if (vm->major_version < VM_MINMAJOR || (vm->major_version == VM_MINMAJOR && vm->minor_version < VM_MINMINOR)) {
+ if (vm->major_version < VM_MINMAJOR ||
+ (vm->major_version == VM_MINMAJOR && vm->minor_version < VM_MINMINOR)) {
nv_warning_msg("The version of the XF86VidMode extension present "
"on this display (%d.%d) does not support updating "
"gamma ramps. If you'd like to be able to adjust "
"gamma ramps, please update your X server such that "
"the version of the XF86VidMode extension is %d.%d "
- "or higher.", vm->major_version, vm->minor_version, VM_MINMAJOR, VM_MINMINOR);
+ "or higher.", vm->major_version, vm->minor_version,
+ VM_MINMAJOR, VM_MINMINOR);
goto failed;
}
- /*
- * XXX setup an error handler to catch any errors caused by the
- * VidMode extension blocking remote clients; we'll restore the
- * original error handler below
- */
-
- prev_error_handler = XSetErrorHandler(vidModeErrorHandler);
-
- ret = XF86VidModeGetGammaRampSize(h->dpy, h->target_id, &vm->n);
-
- /* check if XF86VidModeGetGammaRampSize was blocked */
-
- if (vidModeBlocked) {
- goto blocked;
+ ret = XF86VidModeGetPermissions(h->dpy, h->target_id, &permissions);
+
+ if (!ret) {
+ goto failed;
}
-
- if (ret != True) goto failed;
-
- vm->lut[RED] = malloc(sizeof(unsigned short) * vm->n);
- vm->lut[GREEN] = malloc(sizeof(unsigned short) * vm->n);
- vm->lut[BLUE] = malloc(sizeof(unsigned short) * vm->n);
-
- ret = XF86VidModeGetGammaRamp(h->dpy, h->target_id, vm->n, vm->lut[RED],
- vm->lut[GREEN], vm->lut[BLUE]);
-
- /* check if XF86VidModeGetGammaRamp was blocked */
- if (vidModeBlocked) {
- goto blocked;
+ if (((permissions & XF86VM_READ_PERMISSION) == 0) ||
+ ((permissions & XF86VM_WRITE_PERMISSION) == 0)) {
+ goto failed;
}
- if (ret != True) goto failed;
-
- /*
- * XXX Currently, XF86VidModeSetGammaRamp() is the only other
- * XF86VidMode protocol we send, and depending on the XFree86
- * version, it may induce an X error for remote clients. So, try
- * sending it here to see if we get an error (yes, this is the
- * data we just retrieved above from XF86VidModeGetGammaRamp).
- * It's terrible that we have to do this.
- */
-
- ret = XF86VidModeSetGammaRamp(h->dpy, h->target_id, vm->n,
- vm->lut[RED],
- vm->lut[GREEN],
- vm->lut[BLUE]);
- /*
- * sync the protocol stream to make sure we process any X error
- * before continuing
- */
-
- XSync(h->dpy, False);
- /* check if XF86VidModeSetGammaRamp was blocked */
-
- if (vidModeBlocked) {
- goto blocked;
- }
-
- /* finally, restore the original error handler */
-
- XSetErrorHandler(prev_error_handler);
-
- /*
- * XXX can we initialize this to anything based on the current
- * ramps?
- */
-
- for (i = RED; i <= BLUE; i++) {
- vm->brightness[i] = BRIGHTNESS_DEFAULT;
- vm->contrast[i] = CONTRAST_DEFAULT;
- vm->gamma[i] = GAMMA_DEFAULT;
+ ret = XF86VidModeGetGammaRampSize(h->dpy, h->target_id, &size);
+
+ if (!ret) goto failed;
+
+ vm->lut[RED_CHANNEL_INDEX] = malloc(sizeof(unsigned short) * size);
+ vm->lut[GREEN_CHANNEL_INDEX] = malloc(sizeof(unsigned short) * size);
+ vm->lut[BLUE_CHANNEL_INDEX] = malloc(sizeof(unsigned short) * size);
+
+ if ((vm->lut[RED_CHANNEL_INDEX] == NULL) ||
+ (vm->lut[GREEN_CHANNEL_INDEX] == NULL) ||
+ (vm->lut[BLUE_CHANNEL_INDEX] == NULL)) {
+ goto failed;
}
-
- /* take log2 of vm->n to find the sigbits */
-
- for (i = 0; ((vm->n >> i) > 0); i++);
- vm->sigbits = i - 1;
-
- return (vm);
- blocked:
-
- nv_warning_msg("The VidMode extension is blocked for remote "
- "clients. To allow remote VidMode clients, the "
- "XF86Config option \"AllowNonLocalXvidtune\" must be "
- "set in the ServerFlags section of the XF86Config "
- "file.");
-
- /* fall through */
+ vm->gammaRampSize = size;
- failed:
- if (vm) free(vm);
+ ret = XF86VidModeGetGammaRamp(h->dpy, h->target_id, size,
+ vm->lut[RED_CHANNEL_INDEX],
+ vm->lut[GREEN_CHANNEL_INDEX],
+ vm->lut[BLUE_CHANNEL_INDEX]);
+ if (!ret) goto failed;
+
+ NvCtrlInitGammaInputStruct(&vm->gammaInput);
- /* restore the original error handler, if we overrode it */
+ return vm;
- if (prev_error_handler) {
- XSetErrorHandler(prev_error_handler);
- prev_error_handler = NULL;
+ failed:
+ if (vm) {
+ free(vm->lut[RED_CHANNEL_INDEX]);
+ free(vm->lut[GREEN_CHANNEL_INDEX]);
+ free(vm->lut[BLUE_CHANNEL_INDEX]);
+ free(vm);
}
return NULL;
@@ -203,22 +111,19 @@ NvCtrlInitVidModeAttributes(NvCtrlAttributePrivateHandle *h)
} /* NvCtrlInitVidModeAttributes() */
-ReturnStatus NvCtrlGetColorAttributes(NvCtrlAttributeHandle *handle,
- float contrast[3],
- float brightness[3],
- float gamma[3])
+ReturnStatus NvCtrlVidModeGetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float contrast[3],
+ float brightness[3],
+ float gamma[3])
{
int i;
- NvCtrlAttributePrivateHandle *h;
-
- h = (NvCtrlAttributePrivateHandle *) handle;
if (!h->vm) return NvCtrlMissingExtension;
- for (i = RED; i <= BLUE; i++) {
- contrast[i] = h->vm->contrast[i];
- brightness[i] = h->vm->brightness[i];
- gamma[i] = h->vm->gamma[i];
+ for (i = FIRST_COLOR_CHANNEL; i <= LAST_COLOR_CHANNEL; i++) {
+ contrast[i] = h->vm->gammaInput.contrast[i];
+ brightness[i] = h->vm->gammaInput.brightness[i];
+ gamma[i] = h->vm->gammaInput.gamma[i];
}
return NvCtrlSuccess;
@@ -245,172 +150,62 @@ ReturnStatus NvCtrlGetColorAttributes(NvCtrlAttributeHandle *handle,
* it to the X server.
*/
-ReturnStatus NvCtrlSetColorAttributes(NvCtrlAttributeHandle *handle,
- float c[3],
- float b[3],
- float g[3],
- unsigned int bitmask)
+ReturnStatus NvCtrlVidModeSetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float c[3],
+ float b[3],
+ float g[3],
+ unsigned int bitmask)
{
- int i, ch;
Bool ret;
-
- NvCtrlAttributePrivateHandle *h;
- h = (NvCtrlAttributePrivateHandle *) handle;
-
- /* Check parameters */
if (!h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN) {
return NvCtrlBadHandle;
}
- if (!h->vm) return NvCtrlMissingExtension;
- /* clamp input, but only the input specified in the bitmask */
-
- for (ch = RED; ch <= BLUE; ch++) {
- if (bitmask & (1 << ch)) {
- if (bitmask & CONTRAST_VALUE) {
- if (c[ch] > CONTRAST_MAX) c[ch] = CONTRAST_MAX;
- if (c[ch] < CONTRAST_MIN) c[ch] = CONTRAST_MIN;
- }
- if (bitmask & BRIGHTNESS_VALUE) {
- if (b[ch] > BRIGHTNESS_MAX) b[ch] = BRIGHTNESS_MAX;
- if (b[ch] < BRIGHTNESS_MIN) b[ch] = BRIGHTNESS_MIN;
- }
- if (bitmask & GAMMA_VALUE) {
- if (g[ch] > GAMMA_MAX) g[ch] = GAMMA_MAX;
- if (g[ch] < GAMMA_MIN) g[ch] = GAMMA_MIN;
- }
- }
+ if (!h->vm) {
+ return NvCtrlMissingExtension;
}
-
- /* assign specified values */
- if (bitmask & CONTRAST_VALUE) {
- if (bitmask & RED_CHANNEL) h->vm->contrast[RED] = c[RED];
- if (bitmask & GREEN_CHANNEL) h->vm->contrast[GREEN] = c[GREEN];
- if (bitmask & BLUE_CHANNEL) h->vm->contrast[BLUE] = c[BLUE];
- }
+ NvCtrlAssignGammaInput(&h->vm->gammaInput, c, b, g, bitmask);
- if (bitmask & BRIGHTNESS_VALUE) {
- if (bitmask & RED_CHANNEL) h->vm->brightness[RED] = b[RED];
- if (bitmask & GREEN_CHANNEL) h->vm->brightness[GREEN] = b[GREEN];
- if (bitmask & BLUE_CHANNEL) h->vm->brightness[BLUE] = b[BLUE];
- }
-
- if (bitmask & GAMMA_VALUE) {
- if (bitmask & RED_CHANNEL) h->vm->gamma[RED] = g[RED];
- if (bitmask & GREEN_CHANNEL) h->vm->gamma[GREEN] = g[GREEN];
- if (bitmask & BLUE_CHANNEL) h->vm->gamma[BLUE] = g[BLUE];
- }
+ NvCtrlUpdateGammaRamp(&h->vm->gammaInput,
+ h->vm->gammaRampSize,
+ h->vm->lut,
+ bitmask);
- for (ch = RED; ch <= BLUE; ch++) {
- if ( !(bitmask & (1 << ch))) continue; /* don't update this channel */
- for (i = 0; i < h->vm->n; i++) {
- h->vm->lut[ch][i] = computeVal(h, i, h->vm->contrast[ch],
- h->vm->brightness[ch],
- h->vm->gamma[ch]);
- }
- }
-
- ret = XF86VidModeSetGammaRamp(h->dpy, h->target_id, h->vm->n,
- h->vm->lut[RED],
- h->vm->lut[GREEN],
- h->vm->lut[BLUE]);
-
- if (ret != True) return NvCtrlError;
+ ret = XF86VidModeSetGammaRamp(h->dpy, h->target_id, h->vm->gammaRampSize,
+ h->vm->lut[RED_CHANNEL_INDEX],
+ h->vm->lut[GREEN_CHANNEL_INDEX],
+ h->vm->lut[BLUE_CHANNEL_INDEX]);
- return NvCtrlSuccess;
-
-} /* NvCtrlSetColorAttribute() */
+ return ret ? NvCtrlSuccess : NvCtrlError;
+}
-ReturnStatus NvCtrlGetColorRamp(NvCtrlAttributeHandle *handle,
- unsigned int channel,
- unsigned short **lut,
- int *n)
+ReturnStatus NvCtrlVidModeGetColorRamp(NvCtrlAttributePrivateHandle *h,
+ unsigned int channel,
+ unsigned short **lut,
+ int *n)
{
- NvCtrlAttributePrivateHandle *h;
-
- h = (NvCtrlAttributePrivateHandle *) handle;
-
- /* Check parameters */
if (!h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN) {
return NvCtrlBadHandle;
}
- if (!h->vm) return NvCtrlMissingExtension;
+ if (!h->vm) {
+ return NvCtrlMissingExtension;
+ }
+
+ *n = h->vm->gammaRampSize;
- *n = h->vm->n;
-
switch (channel) {
- case RED_CHANNEL: *lut = h->vm->lut[RED]; break;
- case GREEN_CHANNEL: *lut = h->vm->lut[GREEN]; break;
- case BLUE_CHANNEL: *lut = h->vm->lut[BLUE]; break;
+ case RED_CHANNEL: *lut = h->vm->lut[RED_CHANNEL_INDEX]; break;
+ case GREEN_CHANNEL: *lut = h->vm->lut[GREEN_CHANNEL_INDEX]; break;
+ case BLUE_CHANNEL: *lut = h->vm->lut[BLUE_CHANNEL_INDEX]; break;
default: return NvCtrlBadArgument;
}
return NvCtrlSuccess;
}
-
-/*
- * computeVal() - compute the LUT entry given its index, and the
- * contrast, brightness, and gamma.
- */
-static unsigned short computeVal(NvCtrlAttributePrivateHandle *h,
- int i, float c, float b, float g)
-{
- double j, half, scale;
- int shift, val, num;
-
- num = h->vm->n - 1;
- shift = 16 - h->vm->sigbits;
-
- scale = (double) num / 3.0; /* how much brightness and contrast
- affect the value */
- j = (double) i;
-
- /* contrast */
-
- c *= scale;
-
- if (c > 0.0) {
- half = ((double) num / 2.0) - 1.0;
- j -= half;
- j *= half / (half - c);
- j += half;
- } else {
- half = (double) num / 2.0;
- j -= half;
- j *= (half + c) / half;
- j += half;
- }
-
- if (j < 0.0) j = 0.0;
-
- /* gamma */
-
- g = 1.0 / (double) g;
-
- if (g == 1.0) {
- val = (int) j;
- } else {
- val = (int) (pow (j / (double)num, g) * (double)num + 0.5);
- }
-
- /* brightness */
-
- b *= scale;
-
- val += (int)b;
- if (val > num) val = num;
- if (val < 0) val = 0;
-
- val <<= shift;
- return (unsigned short) val;
-
-} /* computeVal() */
-
-
/*
* Get XF86 Video Mode String Attribute Values
*/
diff --git a/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c b/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
index 99aa756..c9c5eb9 100644
--- a/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
+++ b/src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c
@@ -62,6 +62,21 @@ typedef struct __libXrandrInfoRec {
void (* XRRSelectInput)
(Display *dpy, Window window, int mask);
+ /* gamma-related entry points */
+
+ XRRCrtcGamma *(* XRRGetCrtcGamma)(Display *dpy, RRCrtc crtc);
+
+ void (* XRRSetCrtcGamma)(Display *dpy, RRCrtc crtc, XRRCrtcGamma *gamma);
+
+ void (* XRRFreeGamma)(XRRCrtcGamma *gamma);
+
+ /* output and crtc querying functions */
+
+ XRROutputInfo *(* XRRGetOutputInfo)
+ (Display *dpy, XRRScreenResources *resources, RROutput output);
+
+ void (* XRRFreeOutputInfo)(XRROutputInfo *outputInfo);
+
} __libXrandrInfo;
static __libXrandrInfo *__libXrandr = NULL;
@@ -116,6 +131,24 @@ static Bool open_libxrandr(void)
NV_DLSYM(__libXrandr->handle, "XRRSelectInput");
if ((error_str = dlerror()) != NULL) goto fail;
+ /* the gamma entry points are optional: we don't check dlerror(3) */
+
+ __libXrandr->XRRGetCrtcGamma =
+ NV_DLSYM(__libXrandr->handle, "XRRGetCrtcGamma");
+
+ __libXrandr->XRRSetCrtcGamma =
+ NV_DLSYM(__libXrandr->handle, "XRRSetCrtcGamma");
+
+ __libXrandr->XRRFreeGamma =
+ NV_DLSYM(__libXrandr->handle, "XRRFreeGamma");
+
+ /* the output/crtc functions are optional: we don't check dlerror(3) */
+
+ __libXrandr->XRRGetOutputInfo =
+ NV_DLSYM(__libXrandr->handle, "XRRGetOutputInfo");
+
+ __libXrandr->XRRFreeOutputInfo =
+ NV_DLSYM(__libXrandr->handle, "XRRFreeOutputInfo");
/* Up the ref count */
__libXrandr->ref_count++;
@@ -165,7 +198,78 @@ static void close_libxrandr(void)
} /* close_libxrandr() */
+static RROutput GetRandRCrtcForGamma(NvCtrlAttributePrivateHandle *h,
+ NvCtrlXrandrAttributes *xrandr)
+{
+ int output;
+ RRCrtc crtc;
+ ReturnStatus status;
+ XRROutputInfo *pOutputInfo;
+ XRRScreenResources screenResources;
+
+ /* finding the RandR output only makes sense for display targets */
+
+ if (h->target_type != NV_CTRL_TARGET_TYPE_DISPLAY) {
+ return None;
+ }
+
+ /* if the server does not support gamma manipulation, return */
+
+ if (!xrandr->gammaAvailable) {
+ return None;
+ }
+
+ /*
+ * if the libXrandr library does not provide the needed entry
+ * points, return
+ */
+
+ if ((__libXrandr->XRRGetOutputInfo == NULL) ||
+ (__libXrandr->XRRFreeOutputInfo == NULL)) {
+ return None;
+ }
+
+ status = NvCtrlGetAttribute(h, NV_CTRL_DISPLAY_RANDR_OUTPUT_ID, &output);
+ if (status != NvCtrlSuccess) {
+ return None;
+ }
+
+ if (output == 0) {
+ return None;
+ }
+
+ if ((__libXrandr->XRRGetOutputInfo == NULL) ||
+ (__libXrandr->XRRFreeOutputInfo == NULL)) {
+ return None;
+ }
+
+ /*
+ * XXX Normally, an X client should query XRRGetScreenResources(3)
+ * to get an appropriately initialized XRRScreenResources data
+ * structure. However, XRRGetOutputInfo(3) only uses
+ * XRRScreenResources to get the configTimestamp for the protocol
+ * request, and XRRGetScreenResources(3) can be an expensive
+ * request (triggers reprobing all display hardware, etc). So,
+ * just zero-initialize XRRScreenResources and pass it into
+ * XRRGetOutputInfo().
+ */
+ memset(&screenResources, 0, sizeof(screenResources));
+ screenResources.configTimestamp = CurrentTime;
+
+ pOutputInfo =
+ __libXrandr->XRRGetOutputInfo(h->dpy, &screenResources, output);
+
+ if (pOutputInfo == NULL) {
+ return None;
+ }
+
+ crtc = pOutputInfo->crtc;
+
+ __libXrandr->XRRFreeOutputInfo(pOutputInfo);
+
+ return crtc;
+}
/******************************************************************************
*
@@ -180,10 +284,15 @@ NvCtrlInitXrandrAttributes (NvCtrlAttributePrivateHandle *h)
NvCtrlXrandrAttributes * xrandr = NULL;
/* Check parameters */
- if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
+ if (!h || !h->dpy) {
goto fail;
}
+ /* allow RandR on X_SCREEN and DISPLAY target types */
+ if ((h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN) &&
+ (h->target_type != NV_CTRL_TARGET_TYPE_DISPLAY)) {
+ goto fail;
+ }
/* Open libXrandr.so.2 */
if ( !open_libxrandr() ) {
@@ -208,16 +317,41 @@ NvCtrlInitXrandrAttributes (NvCtrlAttributePrivateHandle *h)
}
/* Verify server version of the XRandR extension */
- if ( !__libXrandr->XRRQueryVersion(h->dpy, &(xrandr->major_version), &(xrandr->minor_version)) ||
+ if ( !__libXrandr->XRRQueryVersion(h->dpy, &(xrandr->major_version),
+ &(xrandr->minor_version)) ||
((xrandr->major_version < MIN_RANDR_MAJOR) ||
((xrandr->major_version == MIN_RANDR_MAJOR) &&
(xrandr->minor_version < MIN_RANDR_MINOR)))) {
goto fail;
}
- /* Register to receive XRandR events */
- __libXrandr->XRRSelectInput(h->dpy, RootWindow(h->dpy, h->target_id),
- RRScreenChangeNotifyMask);
+ /* Register to receive XRandR events if this is an X screen */
+ if (h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) {
+ __libXrandr->XRRSelectInput(h->dpy, RootWindow(h->dpy, h->target_id),
+ RRScreenChangeNotifyMask);
+ }
+
+ /* check if this configuration supports gamma manipulation */
+
+ xrandr->gammaAvailable =
+ ((xrandr->major_version > 1) ||
+ ((xrandr->major_version == 1) && (xrandr->minor_version >= 2))) &&
+ (__libXrandr->XRRSetCrtcGamma != NULL);
+
+
+ /*
+ * get the RandR CRTC and gamma; the mapping of NV-CONTROL display
+ * device target to RandR CRTC could change at each modeset, so
+ * the frontend needs to reallocate this handle after each modeset
+ */
+
+ xrandr->gammaCrtc = GetRandRCrtcForGamma(h, xrandr);
+
+ if ((xrandr->gammaCrtc != None) && (__libXrandr->XRRGetCrtcGamma != NULL)) {
+ xrandr->pGammaRamp =
+ __libXrandr->XRRGetCrtcGamma(h->dpy, xrandr->gammaCrtc);
+ NvCtrlInitGammaInputStruct(&xrandr->gammaInput);
+ }
return xrandr;
@@ -246,6 +380,11 @@ NvCtrlXrandrAttributesClose (NvCtrlAttributePrivateHandle *h)
return;
}
+ if ((h->xrandr->pGammaRamp != NULL) &&
+ (__libXrandr->XRRFreeGamma != NULL)) {
+ __libXrandr->XRRFreeGamma(h->xrandr->pGammaRamp);
+ }
+
close_libxrandr();
free(h->xrandr);
@@ -284,3 +423,123 @@ NvCtrlXrandrGetStringAttribute (NvCtrlAttributePrivateHandle *h,
return NvCtrlNoAttribute;
} /* NvCtrlXrandrGetStringAttribute() */
+
+
+ReturnStatus
+NvCtrlXrandrGetAttribute(NvCtrlAttributePrivateHandle *h,
+ unsigned int display_mask, int attr, int64_t *val)
+{
+ if (!h || !h->xrandr) {
+ return NvCtrlBadHandle;
+ }
+
+ if (attr != NV_CTRL_ATTR_RANDR_GAMMA_AVAILABLE) {
+ return NvCtrlNoAttribute;
+ }
+
+ if (h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN) {
+ *val = h->xrandr->gammaAvailable;
+ } else {
+ *val = (h->xrandr->pGammaRamp != NULL);
+ }
+
+ return NvCtrlSuccess;
+}
+
+ReturnStatus NvCtrlXrandrGetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float contrast[3],
+ float brightness[3],
+ float gamma[3])
+{
+ int i;
+
+ if (!h->xrandr) return NvCtrlMissingExtension;
+
+ for (i = FIRST_COLOR_CHANNEL; i <= LAST_COLOR_CHANNEL; i++) {
+ contrast[i] = h->xrandr->gammaInput.contrast[i];
+ brightness[i] = h->xrandr->gammaInput.brightness[i];
+ gamma[i] = h->xrandr->gammaInput.gamma[i];
+ }
+
+ return NvCtrlSuccess;
+
+}
+
+ReturnStatus NvCtrlXrandrSetColorAttributes(NvCtrlAttributePrivateHandle *h,
+ float c[3],
+ float b[3],
+ float g[3],
+ unsigned int bitmask)
+{
+ unsigned short *tmpGammaArray[3];
+
+ if (!h || !h->dpy) {
+ return NvCtrlBadHandle;
+ }
+
+ if (!h->xrandr) {
+ return NvCtrlMissingExtension;
+ }
+
+ if (h->xrandr->pGammaRamp == NULL) {
+ return NvCtrlMissingExtension;
+ }
+
+ if (h->xrandr->gammaCrtc == None) {
+ return NvCtrlMissingExtension;
+ }
+
+ NvCtrlAssignGammaInput(&h->xrandr->gammaInput, c, b, g, bitmask);
+
+ tmpGammaArray[RED_CHANNEL_INDEX] = h->xrandr->pGammaRamp->red;
+ tmpGammaArray[GREEN_CHANNEL_INDEX] = h->xrandr->pGammaRamp->green;
+ tmpGammaArray[BLUE_CHANNEL_INDEX] = h->xrandr->pGammaRamp->blue;
+
+ NvCtrlUpdateGammaRamp(&h->xrandr->gammaInput,
+ h->xrandr->pGammaRamp->size,
+ tmpGammaArray,
+ bitmask);
+
+ __libXrandr->XRRSetCrtcGamma(h->dpy, h->xrandr->gammaCrtc,
+ h->xrandr->pGammaRamp);
+
+ XFlush(h->dpy);
+
+ return NvCtrlSuccess;
+}
+
+ReturnStatus NvCtrlXrandrGetColorRamp(NvCtrlAttributePrivateHandle *h,
+ unsigned int channel,
+ uint16_t **lut,
+ int *n)
+{
+ if (!h || !h->dpy) {
+ return NvCtrlBadHandle;
+ }
+
+ if (!h->xrandr) {
+ return NvCtrlMissingExtension;
+ }
+
+ if (h->xrandr->pGammaRamp == NULL) {
+ return NvCtrlMissingExtension;
+ }
+
+ *n = h->xrandr->pGammaRamp->size;
+
+ switch (channel) {
+ case RED_CHANNEL:
+ *lut = h->xrandr->pGammaRamp->red;
+ break;
+ case GREEN_CHANNEL:
+ *lut = h->xrandr->pGammaRamp->green;
+ break;
+ case BLUE_CHANNEL:
+ *lut = h->xrandr->pGammaRamp->blue;
+ break;
+ default:
+ return NvCtrlBadArgument;
+ }
+
+ return NvCtrlSuccess;
+}
diff --git a/src/parse.c b/src/parse.c
index e4112dc..efb0ba4 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -305,6 +305,7 @@ AttributeTableEntry attributeTable[] = {
{ "CurrentMetaModeID", NV_CTRL_CURRENT_METAMODE_ID, N, "The ID of the current MetaMode." },
{ "CurrentMetaMode", NV_CTRL_STRING_CURRENT_METAMODE_VERSION_2, S|N, "Controls the current MetaMode." },
{ "XineramaInfoOrder", NV_CTRL_STRING_NVIDIA_XINERAMA_INFO_ORDER, S|N, "Controls the nvidiaXineramaInfoOrder." },
+ { "RandROutputID", NV_CTRL_DISPLAY_RANDR_OUTPUT_ID, N, "The RandR Output ID that corresponds to the display device." },
/* TV */
{ "TVOverScan", NV_CTRL_TV_OVERSCAN, 0, "Adjusts the amount of overscan on the specified display device." },
@@ -367,7 +368,7 @@ AttributeTableEntry attributeTable[] = {
* about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_FXAA
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DISPLAY_RANDR_OUTPUT_ID
#warning "Have you forgotten to add a new integer attribute to attributeTable?"
#endif
diff --git a/src/src.mk b/src/src.mk
index e6c9a15..24a18b6 100644
--- a/src/src.mk
+++ b/src/src.mk
@@ -179,6 +179,7 @@ GTK_SRC += gtk+-2.x/ctkframelock.c
GTK_SRC += gtk+-2.x/ctkgauge.c
GTK_SRC += gtk+-2.x/ctkcurve.c
GTK_SRC += gtk+-2.x/ctkcolorcorrection.c
+GTK_SRC += gtk+-2.x/ctkcolorcorrectionpage.c
GTK_SRC += gtk+-2.x/ctkscale.c
GTK_SRC += gtk+-2.x/ctkmultisample.c
GTK_SRC += gtk+-2.x/ctkconfig.c
@@ -226,6 +227,7 @@ GTK_EXTRA_DIST += gtk+-2.x/ctkframelock.h
GTK_EXTRA_DIST += gtk+-2.x/ctkgauge.h
GTK_EXTRA_DIST += gtk+-2.x/ctkcurve.h
GTK_EXTRA_DIST += gtk+-2.x/ctkcolorcorrection.h
+GTK_EXTRA_DIST += gtk+-2.x/ctkcolorcorrectionpage.h
GTK_EXTRA_DIST += gtk+-2.x/ctkscale.h
GTK_EXTRA_DIST += gtk+-2.x/ctkmultisample.h
GTK_EXTRA_DIST += gtk+-2.x/ctkconfig.h
diff --git a/src/version.mk b/src/version.mk
index c7ccc7a..7753329 100644
--- a/src/version.mk
+++ b/src/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 304.37
+NVIDIA_VERSION = 304.43
diff --git a/version.mk b/version.mk
index c7ccc7a..7753329 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 304.37
+NVIDIA_VERSION = 304.43