summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2008-08-21 10:41:30 -0700
committerAaron Plattner <aplattner@nvidia.com>2008-08-21 10:41:30 -0700
commit2359725ef2dae040185b353d4ce57f40d6452b5c (patch)
tree3ac5709694e979dae2876954b71190146b55e5cd
parent96fec7cf078d5becbd17f0f99a61b5c2f560c797 (diff)
177.67177.67
-rw-r--r--doc/nvidia-settings.1.m46
-rw-r--r--src/Makefile.inc6
-rw-r--r--src/XF86Config-parser/Generate.c19
-rw-r--r--src/XF86Config-parser/Merge.c5
-rw-r--r--src/command-line.c2
-rw-r--r--src/glxinfo.c8
-rw-r--r--src/gtk+-2.x/ctkbanner.c7
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.c405
-rw-r--r--src/gtk+-2.x/ctkcolorcorrection.h5
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.c493
-rw-r--r--src/gtk+-2.x/ctkdisplayconfig.h11
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-crt.c8
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-dfp.c9
-rw-r--r--src/gtk+-2.x/ctkdisplaydevice-tv.c8
-rw-r--r--src/gtk+-2.x/ctkdisplaylayout.c267
-rw-r--r--src/gtk+-2.x/ctkdropdownmenu.c37
-rw-r--r--src/gtk+-2.x/ctkdropdownmenu.h3
-rw-r--r--src/gtk+-2.x/ctkevent.c7
-rw-r--r--src/gtk+-2.x/ctkframelock.c6
-rw-r--r--src/gtk+-2.x/ctkgvo-csc.c145
-rw-r--r--src/gtk+-2.x/ctkgvo-csc.h1
-rw-r--r--src/gtk+-2.x/ctkgvo-sync.c255
-rw-r--r--src/gtk+-2.x/ctkgvo.c887
-rw-r--r--src/gtk+-2.x/ctkgvo.h20
-rw-r--r--src/gtk+-2.x/ctkmultisample.c24
-rw-r--r--src/gtk+-2.x/ctkopengl.c304
-rw-r--r--src/gtk+-2.x/ctkopengl.h2
-rw-r--r--src/gtk+-2.x/ctkslimm.c4
-rw-r--r--src/gtk+-2.x/ctkwindow.c42
-rw-r--r--src/libXNVCtrl/NVCtrl.h47
-rw-r--r--src/lscf.c275
-rw-r--r--src/lscf.h31
-rw-r--r--src/parse.c13
33 files changed, 2365 insertions, 997 deletions
diff --git a/doc/nvidia-settings.1.m4 b/doc/nvidia-settings.1.m4
index d21eff5..c968846 100644
--- a/doc/nvidia-settings.1.m4
+++ b/doc/nvidia-settings.1.m4
@@ -578,12 +578,6 @@ There are many things still to be added to
some of which include:
.TP
-
-configurability of TwinView (NVIDIA is planning to implement this)
-.TP
--
-configurability of multiple X screens (NVIDIA is planning to implement this)
-.TP
--
different toolkits?
The GUI for
.B nvidia\-settings
diff --git a/src/Makefile.inc b/src/Makefile.inc
index 1e0f2a8..2dfee54 100644
--- a/src/Makefile.inc
+++ b/src/Makefile.inc
@@ -33,7 +33,8 @@ SRC += \
parse.c \
query-assign.c \
nvgetopt.c \
- glxinfo.c
+ glxinfo.c \
+ lscf.c
EXTRA_DIST += \
Makefile.inc \
@@ -43,7 +44,8 @@ EXTRA_DIST += \
parse.h \
query-assign.h \
nvgetopt.h \
- glxinfo.h
+ glxinfo.h \
+ lscf.h
dist_list::
@ echo $(SRC) $(EXTRA_DIST)
diff --git a/src/XF86Config-parser/Generate.c b/src/XF86Config-parser/Generate.c
index 0b6c9bd..22ce212 100644
--- a/src/XF86Config-parser/Generate.c
+++ b/src/XF86Config-parser/Generate.c
@@ -48,7 +48,6 @@
static int is_file(const char *filename);
-static void add_files(GenerateOptions *gop, XConfigPtr config);
static void add_font_path(GenerateOptions *gop, XConfigPtr config);
static void add_modules(GenerateOptions *gop, XConfigPtr config);
@@ -72,7 +71,7 @@ XConfigPtr xconfigGenerate(GenerateOptions *gop)
/* add files, fonts, and modules */
- add_files(gop, config);
+ config->files = xconfigAlloc(sizeof(XConfigFilesRec));
add_font_path(gop, config);
add_modules(gop, config);
@@ -255,22 +254,6 @@ static char *find_libdir(GenerateOptions *gop)
/*
- * add_files() -
- */
-
-static void add_files(GenerateOptions *gop, XConfigPtr config)
-{
- char *libdir = find_libdir(gop);
-
- config->files = xconfigAlloc(sizeof(XConfigFilesRec));
- config->files->rgbpath = xconfigStrcat(libdir, "/X11/rgb", NULL);
-
- free(libdir);
-
-} /* add_files() */
-
-
-/*
* add_font_path() - scan through the __font_paths[] array,
* temporarily chop off the ":unscaled" appendage, and check for the
* file "fonts.dir" in the directory. If fonts.dir exists, append the
diff --git a/src/XF86Config-parser/Merge.c b/src/XF86Config-parser/Merge.c
index aaf66bc..7d8ab98 100644
--- a/src/XF86Config-parser/Merge.c
+++ b/src/XF86Config-parser/Merge.c
@@ -479,6 +479,7 @@ static int xconfigMergeDisplays(XConfigScreenPtr dstScreen,
/* Free all the displays in the destination screen */
xconfigFreeDisplayList(dstScreen->displays);
+ dstScreen->displays = NULL;
/* Copy all te displays */
@@ -530,6 +531,10 @@ static int xconfigMergeDisplays(XConfigScreenPtr dstScreen,
srcMode = srcMode->next;
}
+
+ dstScreen->displays =
+ (XConfigDisplayPtr)xconfigAddListItem((GenericListPtr)(dstScreen->displays),
+ (GenericListPtr)dstDisplay);
}
return 1;
diff --git a/src/command-line.c b/src/command-line.c
index b83d706..67616a5 100644
--- a/src/command-line.c
+++ b/src/command-line.c
@@ -73,7 +73,7 @@ static void print_version(void)
nv_msg(TAB, "This program is used to configure the "
"NVIDIA Linux graphics driver.");
nv_msg(NULL, "");
- nv_msg(TAB, "Copyright (C) 2004 NVIDIA Corporation.");
+ nv_msg(TAB, "Copyright (C) 2004 - 2008 NVIDIA Corporation.");
nv_msg(NULL, "");
} /* print_version() */
diff --git a/src/glxinfo.c b/src/glxinfo.c
index 64199eb..23c322b 100644
--- a/src/glxinfo.c
+++ b/src/glxinfo.c
@@ -182,17 +182,17 @@ print_fbconfig_attribs(GLXFBConfigAttr *fbca)
return;
}
- printf("-fc- -vi- vt buf lv rgb d s colorbuffer ax dp st "
+ printf("--fc- -vi- vt buf lv rgb d s colorbuffer ax dp st "
"accumbuffer ---ms---- cav -----pbuffer----- ---transparent----\n");
- printf(" id id siz l ci b t r g b a bf th en "
+ printf(" id id siz l ci b t r g b a bf th en "
" r g b a mvs mcs b eat widt hght max-pxs typ r g b a i\n");
- printf("-------------------------------------------------"
+ printf("--------------------------------------------------"
"--------------------------------------------------------------\n");
i = 0;
while ( fbca[i].fbconfig_id != 0 ) {
- printf("0x%2.2x ", fbca[i].fbconfig_id);
+ printf("0x%03x ", fbca[i].fbconfig_id);
if ( fbca[i].visual_id ) {
printf("0x%2.2x ", fbca[i].visual_id);
} else {
diff --git a/src/gtk+-2.x/ctkbanner.c b/src/gtk+-2.x/ctkbanner.c
index 8e59031..baef5e6 100644
--- a/src/gtk+-2.x/ctkbanner.c
+++ b/src/gtk+-2.x/ctkbanner.c
@@ -429,6 +429,7 @@ GtkWidget* ctk_banner_new(BannerArtworkType artwork)
Background.w = gdk_pixbuf_get_width(Background.pixbuf);
Background.h = gdk_pixbuf_get_height(Background.pixbuf);
}
+ g_object_ref(Background.pixbuf);
if (!TallBackground.pixbuf) {
TallBackground.pixbuf =
@@ -436,12 +437,14 @@ GtkWidget* ctk_banner_new(BannerArtworkType artwork)
TallBackground.w = gdk_pixbuf_get_width(TallBackground.pixbuf);
TallBackground.h = gdk_pixbuf_get_height(TallBackground.pixbuf);
}
+ g_object_ref(TallBackground.pixbuf);
if (!Logo.pixbuf) {
Logo.pixbuf = gdk_pixbuf_from_pixdata(&logo_pixdata, TRUE, NULL);
Logo.w = gdk_pixbuf_get_width(Logo.pixbuf);
Logo.h = gdk_pixbuf_get_height(Logo.pixbuf);
}
+ g_object_ref(Logo.pixbuf);
if (!TallLogo.pixbuf) {
TallLogo.pixbuf =
@@ -449,8 +452,8 @@ GtkWidget* ctk_banner_new(BannerArtworkType artwork)
TallLogo.w = gdk_pixbuf_get_width(TallLogo.pixbuf);
TallLogo.h = gdk_pixbuf_get_height(TallLogo.pixbuf);
}
-
-
+ g_object_ref(TallLogo.pixbuf);
+
/*
* assign fields based on whether the artwork is tall; XXX these
* may need to be tweaked
diff --git a/src/gtk+-2.x/ctkcolorcorrection.c b/src/gtk+-2.x/ctkcolorcorrection.c
index 44722b0..5b2b629 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.c
+++ b/src/gtk+-2.x/ctkcolorcorrection.c
@@ -51,6 +51,13 @@ static const char *__active_color_help = "The Active Color Channel drop-down "
static const char *__resest_button_help = "The Reset Hardware Defaults "
"button restores the color correction settings to their default values.";
+static const char *__confirm_button_help = "Some color correction settings "
+"can yield an unusable display "
+"(e.g., making the display unreadably dark or light). When you "
+"change the color correction values, the '10 Seconds to Confirm' "
+"button will count down to zero. If you have not clicked the "
+"button by then to accept the changes, it will restore your previous values.";
+
static const char *__color_curve_help = "The color curve graph changes to "
"reflect your adjustments made with the Brightness, Constrast, and Gamma "
"sliders.";
@@ -62,17 +69,22 @@ static void
set_button_sensitive (GtkButton *);
static void
-button_clicked (GtkButton *, gpointer);
+reset_button_clicked (GtkButton *, gpointer);
static void
-adjustment_value_changed (GtkAdjustment *, gpointer);
+set_color_state (CtkColorCorrection *, gint, gint, gfloat, gboolean);
+
+static void
+confirm_button_clicked (GtkButton *, gpointer);
+static void
+adjustment_value_changed (GtkAdjustment *, gpointer);
static gfloat
get_attribute_channel_value (CtkColorCorrection *, gint, gint);
static void
-set_attribute_channel_value (CtkColorCorrection *, gint, gint, gfloat);
+flush_attribute_channel_values (CtkColorCorrection *, gint, gint, gfloat);
static void
ctk_color_correction_class_init(CtkColorCorrectionClass *);
@@ -80,6 +92,12 @@ ctk_color_correction_class_init(CtkColorCorrectionClass *);
static void
apply_parsed_attribute_list(CtkColorCorrection *, ParsedAttribute *);
+static gboolean
+do_confirm_countdown (gpointer);
+
+static void
+update_confirm_text (CtkColorCorrection *);
+
enum {
CHANGED,
LAST_SIGNAL
@@ -87,6 +105,15 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
+#define RED RED_CHANNEL_INDEX
+#define GREEN GREEN_CHANNEL_INDEX
+#define BLUE BLUE_CHANNEL_INDEX
+
+#define CONTRAST (CONTRAST_INDEX - CONTRAST_INDEX)
+#define BRIGHTNESS (BRIGHTNESS_INDEX - CONTRAST_INDEX)
+#define GAMMA (GAMMA_INDEX - CONTRAST_INDEX)
+
+#define DEFAULT_CONFIRM_COLORCORRECTION_TIMEOUT 10
#define CREATE_COLOR_ADJUSTMENT(adj, attr, min, max) \
{ \
@@ -171,7 +198,7 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
GtkWidget *rightvbox;
GtkWidget *hbox;
GtkWidget *vbox;
- GtkWidget *button;
+ GtkWidget *button, *confirm_button;
GtkWidget *widget;
GtkWidget *hsep;
GtkWidget *eventbox;
@@ -183,12 +210,20 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
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);
ctk_color_correction->handle = handle;
ctk_color_correction->ctk_config = ctk_config;
-
+ ctk_color_correction->confirm_timer = 0;
+ ctk_color_correction->confirm_countdown =
+ DEFAULT_CONFIRM_COLORCORRECTION_TIMEOUT;
apply_parsed_attribute_list(ctk_color_correction, p);
gtk_box_set_spacing(GTK_BOX(ctk_color_correction), 10);
@@ -327,16 +362,24 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
* settings to their respective default values (for all channels).
*/
- label = gtk_label_new("Reset Hardware Defaults");
hbox = gtk_hbox_new(FALSE, 0);
- button = gtk_button_new();
+ button = gtk_button_new_with_label("Reset Hardware Defaults");
+ gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 15);
- gtk_container_add(GTK_CONTAINER(button), hbox);
+ confirm_button = gtk_button_new_with_label("Confirm Current Changes");
+ gtk_box_pack_end(GTK_BOX(hbox), confirm_button, FALSE, FALSE, 5);
+ gtk_widget_set_sensitive(confirm_button, FALSE);
- g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked),
+ g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(reset_button_clicked),
+ (gpointer) ctk_color_correction);
+
+ g_signal_connect(G_OBJECT(confirm_button), "clicked",
+ G_CALLBACK(confirm_button_clicked),
(gpointer) ctk_color_correction);
+ ctk_color_correction->confirm_button = confirm_button;
+ gtk_widget_set_size_request(confirm_button, 160, -1);
+ ctk_config_set_tooltip(ctk_config, confirm_button, __confirm_button_help);
ctk_config_set_tooltip(ctk_config, button, __resest_button_help);
/*
@@ -450,7 +493,7 @@ GtkWidget* ctk_color_correction_new(NvCtrlAttributeHandle *handle,
*/
alignment = gtk_alignment_new(1, 1, 0, 0);
- gtk_container_add(GTK_CONTAINER(alignment), button);
+ gtk_container_add(GTK_CONTAINER(alignment), hbox);
gtk_box_pack_start(GTK_BOX(object), alignment, TRUE, TRUE, 0);
/* finally, show the widget */
@@ -535,21 +578,89 @@ static void set_button_sensitive(
gtk_widget_set_sensitive (GTK_WIDGET (button), TRUE);
}
-static void button_clicked(
+
+
+/** set_color_state() *******************
+ *
+ * Stores color state to cur_val[attribute][channel]
+ * and prev_val[attribute][channel].
+ *
+ **/
+
+static void set_color_state(CtkColorCorrection *ctk_color_correction,
+ gint attribute_idx, gint channel_idx,
+ gfloat value, gboolean all
+)
+{
+ if ( channel_idx != ALL_CHANNELS ) {
+ ctk_color_correction->cur_val
+ [attribute_idx][channel_idx] = value;
+ if ( all ) {
+ ctk_color_correction->prev_val
+ [attribute_idx][channel_idx] = value;
+ }
+ } else {
+ gint ch;
+ for ( ch = RED; ch <= BLUE; ch++ ) {
+ set_color_state(ctk_color_correction, attribute_idx, ch, value, all);
+ }
+ }
+} /* set_color_state() */
+
+
+
+/** confirm_button_clicked() *************
+ *
+ * Callback function which stores current values to previous value when user
+ * clicks Confirm button.
+ *
+ **/
+
+static void confirm_button_clicked(
+ GtkButton *button,
+ gpointer user_data
+)
+{
+ CtkColorCorrection *ctk_color_correction = CTK_COLOR_CORRECTION(user_data);
+
+ /* Store cur_val[attribute][channel] to prev_val[attribute][channel]. */
+ memcpy (ctk_color_correction->prev_val, ctk_color_correction->cur_val,
+ sizeof(ctk_color_correction->cur_val));
+
+ /* kill the timer */
+ g_source_remove(ctk_color_correction->confirm_timer);
+ ctk_color_correction->confirm_timer = 0;
+
+ /* Reset confirm button text */
+ gtk_button_set_label(GTK_BUTTON(ctk_color_correction->confirm_button),
+ "Confirm Current Changes");
+
+ gtk_widget_set_sensitive(ctk_color_correction->confirm_button, FALSE);
+} /* confirm_button_clicked() */
+
+
+
+static void reset_button_clicked(
GtkButton *button,
gpointer user_data
)
{
CtkColorCorrection *ctk_color_correction;
- gfloat c[3] = {CONTRAST_DEFAULT, CONTRAST_DEFAULT, CONTRAST_DEFAULT};
- gfloat b[3] = {BRIGHTNESS_DEFAULT, BRIGHTNESS_DEFAULT, BRIGHTNESS_DEFAULT};
- gfloat g[3] = {GAMMA_DEFAULT, GAMMA_DEFAULT, GAMMA_DEFAULT};
GtkOptionMenu *option_menu;
-
ctk_color_correction = CTK_COLOR_CORRECTION(user_data);
-
- NvCtrlSetColorAttributes(ctk_color_correction->handle, c, b, g,
- ALL_CHANNELS | ALL_VALUES);
+ /* Set default values */
+ set_color_state(ctk_color_correction, CONTRAST, ALL_CHANNELS,
+ CONTRAST_DEFAULT, TRUE);
+ set_color_state(ctk_color_correction, BRIGHTNESS, ALL_CHANNELS,
+ BRIGHTNESS_DEFAULT, TRUE);
+ set_color_state(ctk_color_correction, GAMMA, ALL_CHANNELS,
+ GAMMA_DEFAULT, TRUE);
+
+ NvCtrlSetColorAttributes(ctk_color_correction->handle,
+ ctk_color_correction->cur_val[CONTRAST],
+ ctk_color_correction->cur_val[BRIGHTNESS],
+ ctk_color_correction->cur_val[GAMMA],
+ ALL_VALUES | ALL_CHANNELS);
option_menu = GTK_OPTION_MENU(ctk_color_correction->option_menu);
@@ -568,7 +679,16 @@ static void button_clicked(
ctk_config_statusbar_message(ctk_color_correction->ctk_config,
"Reset color correction hardware defaults.");
+ gtk_widget_set_sensitive(GTK_WIDGET(ctk_color_correction->confirm_button),
+ FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
+ /* kill the timer */
+ g_source_remove(ctk_color_correction->confirm_timer);
+ ctk_color_correction->confirm_timer = 0;
+
+ /* Reset confirm button text */
+ gtk_button_set_label(GTK_BUTTON(ctk_color_correction->confirm_button),
+ "Confirm Current Changes");
}
static void adjustment_value_changed(
@@ -578,6 +698,7 @@ static void adjustment_value_changed(
{
CtkColorCorrection *ctk_color_correction;
gint attribute, channel;
+ gint attribute_idx, channel_idx;
gfloat value;
gchar *channel_str, *attribute_str;
@@ -591,28 +712,67 @@ static void adjustment_value_changed(
channel = GPOINTER_TO_INT(user_data);
value = gtk_adjustment_get_value(adjustment);
-
- set_attribute_channel_value(ctk_color_correction,
- attribute, channel, value);
+
+ /* start timer for confirming changes */
+ ctk_color_correction->confirm_countdown =
+ DEFAULT_CONFIRM_COLORCORRECTION_TIMEOUT;
+ update_confirm_text(ctk_color_correction);
+
+ if (ctk_color_correction->confirm_timer == 0) {
+ ctk_color_correction->confirm_timer =
+ g_timeout_add(1000,
+ (GSourceFunc)do_confirm_countdown,
+ (gpointer) (ctk_color_correction));
+ }
switch (attribute) {
- case CONTRAST_VALUE: attribute_str = "contrast"; break;
- case BRIGHTNESS_VALUE: attribute_str = "brightness"; break;
- case GAMMA_VALUE: attribute_str = "gamma"; break;
- default: attribute_str = "unknown"; break;
+ case CONTRAST_VALUE:
+ attribute_idx = CONTRAST;
+ attribute_str = "contrast";
+ break;
+ case BRIGHTNESS_VALUE:
+ attribute_idx = BRIGHTNESS;
+ attribute_str = "brightness";
+ break;
+ case GAMMA_VALUE:
+ attribute_idx = GAMMA;
+ attribute_str = "gamma";
+ break;
+ default:
+ return;
}
switch (channel) {
- case RED_CHANNEL: channel_str = "red "; break;
- case GREEN_CHANNEL: channel_str = "green "; break;
- case BLUE_CHANNEL: channel_str = "blue "; break;
- case ALL_CHANNELS: /* fall through */
- default: channel_str = ""; break;
+ case RED_CHANNEL:
+ channel_idx = RED;
+ channel_str = "red ";
+ break;
+ case GREEN_CHANNEL:
+ channel_idx = GREEN;
+ channel_str = "green ";
+ break;
+ case BLUE_CHANNEL:
+ channel_idx = BLUE;
+ channel_str = "blue ";
+ break;
+ case ALL_CHANNELS:
+ channel_idx = ALL_CHANNELS;
+ channel_str = "";
+ break;
+ default:
+ return;
}
+ set_color_state(ctk_color_correction, attribute_idx, channel_idx,
+ value, FALSE);
+
+ flush_attribute_channel_values(ctk_color_correction,
+ attribute, channel, value);
+
ctk_config_statusbar_message(ctk_color_correction->ctk_config,
"Set %s%s to %f.",
channel_str, attribute_str, value);
+ gtk_widget_set_sensitive(ctk_color_correction->confirm_button, TRUE);
}
@@ -652,7 +812,7 @@ static gfloat get_attribute_channel_value(CtkColorCorrection
}
}
-static void set_attribute_channel_value(
+static void flush_attribute_channel_values(
CtkColorCorrection *ctk_color_correction,
gint attribute,
gint channel,
@@ -660,70 +820,88 @@ static void set_attribute_channel_value(
)
{
NvCtrlAttributeHandle *handle = ctk_color_correction->handle;
- gfloat v[3];
- v[0] = v[1] = v[2] = value;
-
- NvCtrlSetColorAttributes(handle, v, v, v, attribute | channel);
+ NvCtrlSetColorAttributes(handle,
+ ctk_color_correction->cur_val[CONTRAST],
+ ctk_color_correction->cur_val[BRIGHTNESS],
+ ctk_color_correction->cur_val[GAMMA],
+ attribute | channel);
g_signal_emit(ctk_color_correction, signals[CHANGED], 0);
}
-#define RED RED_CHANNEL_INDEX
-#define GREEN GREEN_CHANNEL_INDEX
-#define BLUE BLUE_CHANNEL_INDEX
-
static void apply_parsed_attribute_list(
CtkColorCorrection *ctk_color_correction,
ParsedAttribute *p
)
{
- float c[3], b[3], g[3];
- char *this_display_name, *display_name;
+ int target_type, target_id;
unsigned int attr = 0;
- this_display_name = NvCtrlGetDisplayName(ctk_color_correction->handle);
-
- c[0] = c[1] = c[2] = CONTRAST_DEFAULT;
- b[0] = b[1] = b[2] = BRIGHTNESS_DEFAULT;
- g[0] = g[1] = g[2] = GAMMA_DEFAULT;
-
- while (p) {
+ set_color_state(ctk_color_correction, CONTRAST, ALL_CHANNELS,
+ CONTRAST_DEFAULT, TRUE);
+ set_color_state(ctk_color_correction, BRIGHTNESS, ALL_CHANNELS,
+ BRIGHTNESS_DEFAULT, TRUE);
+ set_color_state(ctk_color_correction, GAMMA, ALL_CHANNELS,
+ GAMMA_DEFAULT, TRUE);
- display_name = NULL;
+ target_type = NvCtrlGetTargetType(ctk_color_correction->handle);
+ target_id = NvCtrlGetTargetId(ctk_color_correction->handle);
+
+ while (p) {
if (!p->next) goto next_attribute;
if (!(p->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE)) goto next_attribute;
/*
- * if this parsed attribute's display name does not match the
- * current display name, then ignore
+ * if this parsed attribute's target_type, target_id does not match the
+ * current target_type and target_id then ignore
*/
- display_name = nv_standardize_screen_name(p->display, -1);
-
- if (strcmp(display_name, this_display_name) != 0) goto next_attribute;
+ if ((p->target_type != target_type) ||
+ (p->target_id != target_id)) goto next_attribute;
switch (p->attr & (ALL_VALUES | ALL_CHANNELS)) {
- case (CONTRAST_VALUE | RED_CHANNEL): c[RED] = p->fval; break;
- case (CONTRAST_VALUE | GREEN_CHANNEL): c[GREEN] = p->fval; break;
- case (CONTRAST_VALUE | BLUE_CHANNEL): c[BLUE] = p->fval; break;
+ case (CONTRAST_VALUE | RED_CHANNEL):
+ set_color_state(ctk_color_correction, CONTRAST,
+ RED, p->fval, TRUE); break;
+ case (CONTRAST_VALUE | GREEN_CHANNEL):
+ set_color_state(ctk_color_correction, CONTRAST,
+ GREEN, p->fval, TRUE); break;
+ case (CONTRAST_VALUE | BLUE_CHANNEL):
+ set_color_state(ctk_color_correction, CONTRAST,
+ BLUE, p->fval, TRUE); break;
case (CONTRAST_VALUE | ALL_CHANNELS):
- c[RED] = c[GREEN] = c[BLUE] = p->fval; break;
-
- case (BRIGHTNESS_VALUE | RED_CHANNEL): b[RED] = p->fval; break;
- case (BRIGHTNESS_VALUE | GREEN_CHANNEL): b[GREEN] = p->fval; break;
- case (BRIGHTNESS_VALUE | BLUE_CHANNEL): b[BLUE] = p->fval; break;
+ set_color_state(ctk_color_correction, CONTRAST,
+ ALL_CHANNELS, p->fval, TRUE); break;
+
+ case (BRIGHTNESS_VALUE | RED_CHANNEL):
+ set_color_state(ctk_color_correction, BRIGHTNESS,
+ RED, p->fval, TRUE); break;
+ case (BRIGHTNESS_VALUE | GREEN_CHANNEL):
+ set_color_state(ctk_color_correction, BRIGHTNESS,
+ GREEN, p->fval, TRUE); break;
+ case (BRIGHTNESS_VALUE | BLUE_CHANNEL):
+ set_color_state(ctk_color_correction, BRIGHTNESS,
+ BLUE, p->fval, TRUE); break;
case (BRIGHTNESS_VALUE | ALL_CHANNELS):
- b[RED] = b[GREEN] = b[BLUE] = p->fval; break;
-
- case (GAMMA_VALUE | RED_CHANNEL): g[RED] = p->fval; break;
- case (GAMMA_VALUE | GREEN_CHANNEL): g[GREEN] = p->fval; break;
- case (GAMMA_VALUE | BLUE_CHANNEL): g[BLUE] = p->fval; break;
+ set_color_state(ctk_color_correction, BRIGHTNESS,
+ ALL_CHANNELS, p->fval, TRUE); break;
+
+ case (GAMMA_VALUE | RED_CHANNEL):
+ set_color_state(ctk_color_correction, GAMMA,
+ RED, p->fval, TRUE); break;
+ case (GAMMA_VALUE | GREEN_CHANNEL):
+ set_color_state(ctk_color_correction, GAMMA,
+ GREEN, p->fval, TRUE); break;
+ case (GAMMA_VALUE | BLUE_CHANNEL):
+ set_color_state(ctk_color_correction, GAMMA,
+ BLUE, p->fval, TRUE); break;
case (GAMMA_VALUE | ALL_CHANNELS):
- g[RED] = g[GREEN] = g[BLUE] = p->fval; break;
+ set_color_state(ctk_color_correction, GAMMA,
+ ALL_CHANNELS, p->fval, TRUE); break;
default:
goto next_attribute;
@@ -733,19 +911,95 @@ static void apply_parsed_attribute_list(
next_attribute:
- if (display_name) free(display_name);
-
p = p->next;
}
- free(this_display_name);
-
if (attr) {
- NvCtrlSetColorAttributes(ctk_color_correction->handle, c, b, g, attr);
+ NvCtrlSetColorAttributes(ctk_color_correction->handle,
+ ctk_color_correction->cur_val[CONTRAST],
+ ctk_color_correction->cur_val[BRIGHTNESS],
+ ctk_color_correction->cur_val[GAMMA],
+ attr);
}
} /* apply_parsed_attribute_list() */
+/** update_confirm_text() ************************************
+ *
+ * Generates the text used to lable confirmation button.
+ *
+ **/
+
+static void update_confirm_text(CtkColorCorrection *ctk_color_correction)
+{
+ gchar *str;
+ str = g_strdup_printf("%d Seconds to Confirm",
+ ctk_color_correction->confirm_countdown);
+ gtk_button_set_label(GTK_BUTTON(ctk_color_correction->confirm_button),
+ str);
+ g_free(str);
+} /* update_confirm_text() */
+
+/** do_confirm_countdown() ***********************************
+ *
+ * timeout callback for reverting color correction slider changes if user not
+ * confirm changes.
+ *
+ **/
+
+static gboolean do_confirm_countdown(gpointer data)
+{
+ gint attr, ch;
+ CtkColorCorrection *ctk_color_correction = (CtkColorCorrection *)(data);
+ unsigned int active_attributes_channels = 0;
+ GtkOptionMenu *option_menu =
+ GTK_OPTION_MENU(ctk_color_correction->option_menu);
+
+ ctk_color_correction->confirm_countdown--;
+ if (ctk_color_correction->confirm_countdown > 0) {
+ update_confirm_text(ctk_color_correction);
+ return True;
+ }
+
+ /* Countdown timed out, reset color settings to previous state */
+ for (attr = CONTRAST_INDEX; attr <= GAMMA_INDEX; attr++) {
+ for (ch = RED; ch <= BLUE; ch++) {
+ /* Check for attribute channel value change. */
+ if (ctk_color_correction->cur_val[attr - CONTRAST_INDEX][ch] !=
+ ctk_color_correction->prev_val[attr - CONTRAST_INDEX][ch]) {
+ ctk_color_correction->cur_val[attr - CONTRAST_INDEX][ch] =
+ ctk_color_correction->prev_val[attr - CONTRAST_INDEX][ch];
+ active_attributes_channels |= (1 << attr) | (1 << ch);
+ }
+ }
+ }
+ if (active_attributes_channels) {
+ NvCtrlSetColorAttributes(ctk_color_correction->handle,
+ ctk_color_correction->cur_val[CONTRAST],
+ ctk_color_correction->cur_val[BRIGHTNESS],
+ ctk_color_correction->cur_val[GAMMA],
+ active_attributes_channels);
+ g_signal_emit(ctk_color_correction, signals[CHANGED], 0);
+ }
+
+ /* Refresh color correction page for current selected channel. */
+ option_menu_changed(option_menu, (gpointer)(ctk_color_correction));
+
+ /* Reset confirm button text */
+ gtk_button_set_label(GTK_BUTTON(ctk_color_correction->confirm_button),
+ "Confirm Current Changes");
+
+ /* Update status bar message */
+ ctk_config_statusbar_message(ctk_color_correction->ctk_config,
+ "Reverted color correction changes, due to "
+ "confirmation timeout.");
+
+
+ ctk_color_correction->confirm_timer = 0;
+ gtk_widget_set_sensitive(ctk_color_correction->confirm_button, FALSE);
+ return False;
+
+} /* do_confirm_countdown() */
GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table)
@@ -785,6 +1039,9 @@ GtkTextBuffer *ctk_color_correction_create_help(GtkTextTagTable *table)
"the XF86VidMode extension to manipulate the X screen's "
"color ramps.");
+ 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);
diff --git a/src/gtk+-2.x/ctkcolorcorrection.h b/src/gtk+-2.x/ctkcolorcorrection.h
index a25b2ce..746a787 100644
--- a/src/gtk+-2.x/ctkcolorcorrection.h
+++ b/src/gtk+-2.x/ctkcolorcorrection.h
@@ -64,6 +64,11 @@ struct _CtkColorCorrection
GtkObject *brightness_adjustment;
GtkObject *contrast_adjustment;
GtkObject *gamma_adjustment;
+ GtkWidget *confirm_button;
+ gint confirm_countdown;
+ guint confirm_timer;
+ gfloat cur_val[3][3]; // as [attribute][channel]
+ gfloat prev_val[3][3]; // as [attribute][channel]
guint enabled_display_devices;
};
diff --git a/src/gtk+-2.x/ctkdisplayconfig.c b/src/gtk+-2.x/ctkdisplayconfig.c
index 8381b86..33c291e 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.c
+++ b/src/gtk+-2.x/ctkdisplayconfig.c
@@ -42,6 +42,7 @@
#include "msg.h"
#include "parse.h"
+#include "lscf.h"
#include "ctkutils.h"
@@ -103,7 +104,11 @@ static void validation_details_clicked(GtkWidget *widget, gpointer user_data);
static int generateXConfig(CtkDisplayConfig *ctk_object, XConfigPtr *pConfig);
static void update_banner(XConfigPtr config);
-
+static void display_config_attribute_changed(GtkObject *object, gpointer arg1,
+ gpointer user_data);
+static void reset_layout(CtkDisplayConfig *ctk_object);
+static gboolean force_layout_reset(gpointer user_data);
+static void user_changed_attributes(CtkDisplayConfig *ctk_object);
@@ -330,6 +335,116 @@ static gboolean layout_supports_depth_30(nvLayoutPtr layout)
+/** register_layout_events() *****************************************
+ *
+ * Registers to display-configuration related events relating to all
+ * parts of the given layout structure.
+ *
+ **/
+
+static void register_layout_events(CtkDisplayConfig *ctk_object)
+{
+ nvLayoutPtr layout = ctk_object->layout;
+ nvScreenPtr screen;
+ nvGpuPtr gpu;
+
+
+ /* Register all Screen/Gpu events. */
+
+ for (gpu = layout->gpus; gpu; gpu = gpu->next) {
+
+ if (!gpu->handle) continue;
+
+ g_signal_connect(G_OBJECT(gpu->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_PROBE_DISPLAYS),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
+ g_signal_connect(G_OBJECT(gpu->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_MODE_SET_EVENT),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
+ for (screen = gpu->screens; screen; screen = screen->next) {
+
+ if (!screen->handle) continue;
+
+ g_signal_connect(G_OBJECT(screen->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_STRING_TWINVIEW_XINERAMA_INFO_ORDER),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
+ g_signal_connect(G_OBJECT(screen->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_ASSOCIATED_DISPLAY_DEVICES),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
+ g_signal_connect(G_OBJECT(screen->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_STRING_MOVE_METAMODE),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
+ g_signal_connect(G_OBJECT(screen->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_STRING_DELETE_METAMODE),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+ }
+ }
+
+} /* register_layout_events() */
+
+
+
+/** unregister_layout_events() *****************************************
+ *
+ * Unregisters display-configuration related events relating to all
+ * parts of the given layout structure as registered by
+
+ * Unregisters all Screen/Gpu events.
+ *
+ **/
+
+static void unregister_layout_events(CtkDisplayConfig *ctk_object)
+{
+ nvLayoutPtr layout = ctk_object->layout;
+ nvScreenPtr screen;
+ nvGpuPtr gpu;
+
+
+ /* Unregister all Screen/Gpu events. */
+
+ for (gpu = layout->gpus; gpu; gpu = gpu->next) {
+
+ if (!gpu->handle) continue;
+
+ /* Unregister all GPU events for this GPU */
+ g_signal_handlers_disconnect_matched(G_OBJECT(gpu->ctk_event),
+ G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+ 0, // Signal ID
+ 0, // Signal Detail
+ NULL, // Closure
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
+ for (screen = gpu->screens; screen; screen = screen->next) {
+
+ if (!screen->handle) continue;
+
+ /* Unregister all screen events for this screen */
+ g_signal_handlers_disconnect_matched(G_OBJECT(screen->ctk_event),
+ G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+ 0, // Signal ID
+ 0, // Signal Detail
+ NULL, // Closure
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+ }
+ }
+
+} /* unregister_layout_events() */
+
+
+
/** consolidate_xinerama() *******************************************
*
* Ensures that all X screens have the same depth if Xinerama is
@@ -879,6 +994,17 @@ GtkWidget * create_validation_apply_dialog(CtkDisplayConfig *ctk_object)
} /* create_validation_apply_dialog() */
+
+static void user_changed_attributes(CtkDisplayConfig *ctk_object)
+{
+ if (ctk_object->forced_reset_allowed) {
+ gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ ctk_object->forced_reset_allowed = FALSE;
+ }
+} /* user_changed_attributes() */
+
+
+
static void screen_primary_display_toggled(GtkWidget *widget,
gpointer user_data)
{
@@ -892,9 +1018,7 @@ static void screen_primary_display_toggled(GtkWidget *widget,
screen->primaryDisplay = display;
}
- /* Make the apply button sensitive to user input */
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
-
+ user_changed_attributes(ctk_object);
} /* screen_primary_display_toggled() */
@@ -984,6 +1108,12 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
ctk_object->ctk_config = ctk_config;
ctk_object->apply_possible = TRUE;
+
+ ctk_object->reset_required = FALSE;
+ ctk_object->forced_reset_allowed = TRUE;
+ ctk_object->notify_user_of_reset = TRUE;
+ ctk_object->ignore_reset_events = FALSE;
+
ctk_object->advanced_mode = FALSE;
/* Set container properties of the object & pack the banner */
@@ -1026,6 +1156,9 @@ GtkWidget* ctk_display_config_new(NvCtrlAttributeHandle *handle,
return GTK_WIDGET(ctk_object);
}
+ /* Register all Screen/Gpu events. */
+ register_layout_events(ctk_object);
+
/* Create the layout widget */
ctk_object->obj_layout = ctk_display_layout_new(handle, ctk_config,
ctk_object->layout,
@@ -2305,7 +2438,6 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
cur_modeline = display->cur_mode->modeline;
-
/* Create the modeline lookup table for the dropdown */
if (ctk_object->resolution_table) {
free(ctk_object->resolution_table);
@@ -2433,11 +2565,14 @@ static void setup_display_resolution_dropdown(CtkDisplayConfig *ctk_object)
} /* setup_display_resolution_dropdown() */
+
+
/** generate_display_modelname_dropdown() ********************************
*
* Generate display modelname dropdown menu.
*
**/
+
static GtkWidget* generate_display_modelname_dropdown
(CtkDisplayConfig *ctk_object, int *cur_idx)
{
@@ -2489,14 +2624,19 @@ static GtkWidget* generate_display_modelname_dropdown
[ctk_object->display_model_table_len++] = display;
}
}
+
return menu;
+
} /* generate_display_modelname_dropdown() */
+
+
/** setup_display_modelname_dropdown() **************************
*
* Setup display modelname dropdown menu.
*
**/
+
static void setup_display_modelname_dropdown(CtkDisplayConfig *ctk_object)
{
GtkWidget *menu;
@@ -2531,13 +2671,14 @@ static void setup_display_modelname_dropdown(CtkDisplayConfig *ctk_object)
gtk_option_menu_set_history
(GTK_OPTION_MENU(ctk_object->mnu_display_model), cur_idx);
-
g_signal_handlers_unblock_by_func
(G_OBJECT(ctk_object->mnu_display_model),
G_CALLBACK(display_modelname_changed), (gpointer) ctk_object);
+
} /* setup_display_modelname_dropdown() */
+
/** setup_display_position_type() ************************************
*
* Sets up the display position type dropdown to reflect the position
@@ -2795,8 +2936,11 @@ static void setup_primary_display(CtkDisplayConfig *ctk_object)
(G_OBJECT(ctk_object->chk_primary_display),
G_CALLBACK(screen_primary_display_toggled),
(gpointer) ctk_object);
+
} /* setup_primary_display() */
+
+
/** setup_display_panning() ******************************************
*
* Sets up the display panning text entry to reflect the currently
@@ -3885,7 +4029,7 @@ void layout_modified_callback(nvLayoutPtr layout, void *data)
/* If the positioning of the X screen changes, we cannot apply */
check_screen_pos_changed(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* layout_modified_callback() */
@@ -4176,9 +4320,19 @@ static void do_enable_display_for_twinview(CtkDisplayConfig *ctk_object,
return;
} else {
+ g_signal_handlers_block_by_func
+ (G_OBJECT(screen->ctk_event),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
/* Make sure other parts of nvidia-settings get updated */
ctk_event_emit(screen->ctk_event, 0,
NV_CTRL_ASSOCIATED_DISPLAY_DEVICES, new_mask);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(screen->ctk_event),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
}
}
@@ -4883,8 +5037,8 @@ static void display_config_clicked(GtkWidget *widget, gpointer user_data)
setup_layout_frame(ctk_object);
setup_display_page(ctk_object);
setup_screen_page(ctk_object);
-
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+
+ user_changed_attributes(ctk_object);
}
} /* display_config_clicked() */
@@ -4937,7 +5091,7 @@ static void display_refresh_changed(GtkWidget *widget, gpointer user_data)
/* Update the modename */
setup_display_modename(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* display_refresh_changed() */
@@ -5004,7 +5158,7 @@ static void display_resolution_changed(GtkWidget *widget, gpointer user_data)
setup_display_panning(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* display_resolution_changed() */
@@ -5092,8 +5246,7 @@ static void display_position_type_changed(GtkWidget *widget,
setup_display_position_offset(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
-
+ user_changed_attributes(ctk_object);
} /* display_position_type_changed() */
@@ -5146,7 +5299,7 @@ static void display_position_relative_changed(GtkWidget *widget,
/* Update the GUI */
setup_display_position_offset(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* display_position_relative_changed() */
@@ -5188,7 +5341,7 @@ static void display_position_offset_activate(GtkWidget *widget,
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
display, CONF_ADJ_ABSOLUTE, NULL, x, y);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* display_position_offset_activate() */
@@ -5283,13 +5436,15 @@ static void screen_depth_changed(GtkWidget *widget, gpointer user_data)
}
ctk_display_layout_set_screen_depth
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), screen, depth);
+ /* Update default screen depth in SMF using libscf functions */
+ update_scf_depth(depth);
consolidate_xinerama(ctk_object, screen);
/* Can't apply screen depth changes */
ctk_object->apply_possible = FALSE;
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_depth_changed() */
@@ -5350,7 +5505,7 @@ static void screen_position_type_changed(GtkWidget *widget,
setup_screen_position_offset(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_position_type_changed() */
@@ -5404,7 +5559,7 @@ static void screen_position_relative_changed(GtkWidget *widget,
/* Update the GUI */
setup_screen_position_offset(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_position_relative_changed() */
@@ -5446,7 +5601,7 @@ static void screen_position_offset_activate(GtkWidget *widget,
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout),
screen, screen->position_type, screen->relative_to, x, y);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_position_offset_activate() */
@@ -5533,7 +5688,7 @@ static void screen_metamode_activate(GtkWidget *widget, gpointer user_data)
/* Sync the display frame */
setup_display_page(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_metamode_activate() */
@@ -5563,7 +5718,7 @@ static void screen_metamode_add_clicked(GtkWidget *widget, gpointer user_data)
setup_display_page(ctk_object);
setup_screen_page(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_metamode_add_clicked() */
@@ -5593,7 +5748,7 @@ static void screen_metamode_delete_clicked(GtkWidget *widget,
setup_display_page(ctk_object);
setup_screen_page(ctk_object);
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
} /* screen_metamode_delete_clicked() */
@@ -5620,9 +5775,8 @@ static void xinerama_state_toggled(GtkWidget *widget, gpointer user_data)
consolidate_xinerama(ctk_object, NULL);
setup_screen_page(ctk_object);
- /* Make the apply button sensitive to user input */
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
-
+ user_changed_attributes(ctk_object);
+
} /* xinerama_state_toggled() */
@@ -6148,7 +6302,9 @@ static int update_screen_metamodes(CtkDisplayConfig *ctk_object,
/* If we need to switch metamodes, do so now */
if (strcmp(screen->cur_metamode->string, metamode_str)) {
+
if (switch_to_current_metamode(ctk_object, screen)) {
+
ctk_config_statusbar_message(ctk_object->ctk_config,
"Switched to MetaMode %dx%d.",
screen->cur_metamode->edim[W],
@@ -6186,7 +6342,7 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data)
CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
nvGpuPtr gpu;
ReturnStatus ret;
- int clear_apply = 1;
+ gboolean clear_apply = TRUE;
/* Make sure we can apply */
@@ -6199,6 +6355,9 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data)
return;
}
+ /* Temporarily unregister events */
+ unregister_layout_events(ctk_object);
+
/* Update all GPUs */
for (gpu = ctk_object->layout->gpus; gpu; gpu = gpu->next) {
nvScreenPtr screen;
@@ -6232,7 +6391,8 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data)
if (screen->primaryDisplay) {
gchar *primary_str =
- display_get_type_str(screen->primaryDisplay->device_mask, 0);
+ display_get_type_str(screen->primaryDisplay->device_mask,
+ 0);
ret = NvCtrlSetStringAttribute(screen->handle,
NV_CTRL_STRING_TWINVIEW_XINERAMA_INFO_ORDER,
@@ -6255,8 +6415,21 @@ static void apply_clicked(GtkWidget *widget, gpointer user_data)
/* Clear the apply button if all went well */
if (clear_apply) {
gtk_widget_set_sensitive(widget, False);
+ ctk_object->forced_reset_allowed = TRUE;
+ }
+
+ /* XXX Run the GTK main loop to flush any pending layout events
+ * that should be ignored. This is done because the GTK main loop
+ * seems to only ignore the first blocked event received when it
+ * finally runs.
+ */
+ while (gtk_events_pending()) {
+ gtk_main_iteration_do(FALSE);
}
+ /* re-register to receive events */
+ register_layout_events(ctk_object);
+
} /* apply_clicked() */
@@ -6393,7 +6566,7 @@ static gboolean update_xconfig_save_buffer(CtkDisplayConfig *ctk_object)
/* Find out if the file is mergable */
- if (!filename) {
+ if (!filename || (filename[0] == '\0')) {
mergable = FALSE;
} else {
/* Must be able to open the file */
@@ -6805,7 +6978,7 @@ static XConfigDevicePtr add_device_to_xconfig(nvGpuPtr gpu, XConfigPtr config,
/* Fill out the device information */
device->identifier = (char *)malloc(32);
- snprintf(device->identifier, 32, "Videocard%d", device_id);
+ snprintf(device->identifier, 32, "Device%d", device_id);
device->driver = xconfigStrdup("nvidia");
device->vendor = xconfigStrdup("NVIDIA Corporation");
@@ -7679,11 +7852,15 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data)
gchar *type;
gchar *str;
-
/* Probe each GPU for display changes */
for (gpu = ctk_object->layout->gpus; gpu; gpu = gpu->next) {
+
if (!gpu->handle) continue;
-
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(gpu->ctk_event),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
/* Do the probe */
ret = NvCtrlGetAttribute(gpu->handle, NV_CTRL_PROBE_DISPLAYS,
@@ -7691,6 +7868,12 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data)
if (ret != NvCtrlSuccess) {
nv_error_msg("Failed to probe for display devices on GPU-%d '%s'.",
NvCtrlGetTargetId(gpu->handle), gpu->name);
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(gpu->ctk_event),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
+
continue;
}
@@ -7745,8 +7928,7 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data)
ctk_display_layout_update_display_count
(CTK_DISPLAY_LAYOUT(ctk_object->obj_layout), NULL);
- /* Activate the apply button */
- gtk_widget_set_sensitive(ctk_object->btn_apply, True);
+ user_changed_attributes(ctk_object);
}
/* Add new displays as 'disabled' */
@@ -7764,6 +7946,11 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data)
selected_display);
}
}
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(gpu->ctk_event),
+ G_CALLBACK(display_config_attribute_changed),
+ (gpointer) ctk_object);
}
@@ -7778,6 +7965,68 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data)
+/** reset_layout() *************************************************
+ *
+ * Load current X server settings.
+ *
+ **/
+
+static void reset_layout(CtkDisplayConfig *ctk_object)
+{
+ gchar *err_str = NULL;
+ nvLayoutPtr layout;
+ /* Load the current layout */
+ layout = layout_load_from_server(ctk_object->handle, &err_str);
+
+
+ /* Handle errors loading the new layout */
+ if (!layout || err_str) {
+ nv_error_msg(err_str);
+ g_free(err_str);
+ return;
+ }
+
+
+ /* Free existing layout */
+ unregister_layout_events(ctk_object);
+ layout_free(ctk_object->layout);
+
+
+ /* Setup the new layout */
+ ctk_object->layout = layout;
+ ctk_display_layout_set_layout((CtkDisplayLayout *)(ctk_object->obj_layout),
+ ctk_object->layout);
+
+ register_layout_events(ctk_object);
+
+
+ /* Make sure all X screens have the same depth if Xinerama is enabled */
+ consolidate_xinerama(ctk_object, NULL);
+
+ /* Make sure X screens have some kind of position */
+ assign_screen_positions(ctk_object);
+
+
+ /* Setup the GUI */
+ setup_layout_frame(ctk_object);
+ setup_display_page(ctk_object);
+ setup_screen_page(ctk_object);
+
+ /* Get new position */
+ get_cur_screen_pos(ctk_object);
+
+ /* Clear the apply button */
+ ctk_object->apply_possible = TRUE;
+ gtk_widget_set_sensitive(ctk_object->btn_apply, FALSE);
+
+ ctk_object->forced_reset_allowed = TRUE; /* OK to reset w/o user input */
+ ctk_object->notify_user_of_reset = TRUE; /* Notify user of new changes */
+ ctk_object->reset_required = FALSE; /* No reset required to apply */
+
+} /* reset_layout() */
+
+
+
/** reset_clicked() **************************************************
*
* Called when user clicks on the "Reset" button.
@@ -7787,9 +8036,7 @@ static void probe_clicked(GtkWidget *widget, gpointer user_data)
static void reset_clicked(GtkWidget *widget, gpointer user_data)
{
CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(user_data);
- nvLayoutPtr layout;
gint result;
- gchar *err_str = NULL;
/* Show the confirm dialog */
@@ -7813,48 +8060,168 @@ static void reset_clicked(GtkWidget *widget, gpointer user_data)
return;
}
+ reset_layout(ctk_object);
- /* Load the current layout */
- layout = layout_load_from_server(ctk_object->handle, &err_str);
+} /* reset_clicked() */
- /* Handle errors loading the new layout */
- if (!layout || err_str) {
- nv_error_msg(err_str);
- g_free(err_str);
- return;
- }
+/** force_layout_reset() ******************************************
+ *
+ * Pop up dialog box to user when the layout needs to be reloaded
+ * due to changes made to the server layout by another client.
+ *
+ **/
- /* Free the existing layout */
- layout_free(ctk_object->layout);
+static gboolean force_layout_reset(gpointer user_data)
+{
+ gint result;
+ GtkWidget *parent;
+ GtkWidget *dlg;
+ CtkDisplayConfig *ctk_object = (CtkDisplayConfig *) user_data;
+ if ((ctk_object->forced_reset_allowed) ) {
+ /* It is OK to force a reset of the layout since no
+ * changes have been made.
+ */
+ reset_layout(ctk_object);
+ goto done;
+ }
- /* Setup the new layout */
- ctk_object->layout = layout;
- ctk_display_layout_set_layout((CtkDisplayLayout *)(ctk_object->obj_layout),
- ctk_object->layout);
+ /* It is not OK to force a reset of the layout since the user
+ * may have changed some settings. The user will need to
+ * reset the layout manually.
+ */
- /* Make sure all X screens have the same depth if Xinerama is enabled */
- consolidate_xinerama(ctk_object, NULL);
+ ctk_object->reset_required = TRUE;
- /* Make sure X screens have some kind of position */
- assign_screen_positions(ctk_object);
+ /* If the X server display configuration page is not currently
+ * selected, we will need to notify the user once they get
+ * back to it.
+ */
+ if (!ctk_object->page_selected) goto done;
+ /* Notify the user of the required reset if they haven't
+ * already been notified.
+ */
+ if (!ctk_object->notify_user_of_reset) goto done;
- /* Setup the GUI */
- setup_layout_frame(ctk_object);
- setup_display_page(ctk_object);
- setup_screen_page(ctk_object);
+ parent = ctk_get_parent_window(GTK_WIDGET(ctk_object));
- /* Get new position */
- get_cur_screen_pos(ctk_object);
+ dlg = gtk_message_dialog_new
+ (GTK_WINDOW(parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "Your current changes to the X server display configuration may no "
+ "longer be applied due to changes made to the running X server.\n\n"
+ "You may either reload the current X server settings and lose any "
+ "configuration setup in this page, or select \"Cancel\" and save "
+ "your changes to the X configuration file (requires restarting X "
+ "to take effect.)\n\n"
+ "If you select \"Cancel\", you will only be allowed to apply "
+ "settings once you have reset the configuration.");
+
+ gtk_dialog_add_buttons(GTK_DIALOG(dlg),
+ "Reload current X server settings",
+ GTK_RESPONSE_YES,
+ "Cancel", GTK_RESPONSE_CANCEL,
+ NULL);
+
+ result = gtk_dialog_run(GTK_DIALOG(dlg));
+ switch (result) {
+ case GTK_RESPONSE_YES:
+ reset_layout(ctk_object);
+ break;
+ case GTK_RESPONSE_CANCEL:
+ /* Fall through */
+ default:
+ /* User does not want to reset the layout, don't allow them
+ * to apply their changes (but allow them to save their changes)
+ * until they have reloaded the layout manually.
+ */
+ ctk_object->notify_user_of_reset = FALSE;
+ gtk_widget_set_sensitive(ctk_object->btn_apply, False);
+ break;
+ }
+ gtk_widget_destroy(dlg);
- /* Clear the apply button */
- ctk_object->apply_possible = TRUE;
- gtk_widget_set_sensitive(ctk_object->btn_apply, FALSE);
+done:
+ ctk_object->ignore_reset_events = FALSE;
+ return FALSE;
-} /* reset_clicked() */
+} /* force_layout_reset() */
+
+
+
+/** display_config_attribute_changed() *******************************
+ *
+ * Callback function for all display config page related events
+ * change.
+ *
+ * Display configuration changes usually involve multiple related
+ * events in succession. To avoid reloading the layout for every
+ * event, we register the force_layout_reset() function (once per
+ * block of events) to be called when the app becomes idle (which
+ * will happen once there are no more pending events) using
+ * g_idle_add(). Once force_layout_reset() is called, it will
+ * unresgister itself by returning FALSE.
+ *
+ **/
+
+static void display_config_attribute_changed(GtkObject *object, gpointer arg1,
+ gpointer user_data)
+{
+ CtkDisplayConfig *ctk_object = (CtkDisplayConfig *) user_data;
+
+ if (ctk_object->ignore_reset_events) return;
+
+ ctk_object->ignore_reset_events = TRUE;
+
+ /* queue force_layout_reset() to be called once all other pending
+ * events are consumed.
+ */
+ g_idle_add(force_layout_reset, (gpointer)ctk_object);
+
+} /* display_config_attribute_changed() */
+
+
+
+/** ctk_display_config_unselected() **********************************
+ *
+ * Called when display config page is unselected.
+ *
+ **/
+
+void ctk_display_config_unselected(GtkWidget *widget) {
+ CtkDisplayConfig *ctk_object = CTK_DISPLAY_CONFIG(widget);
+
+ ctk_object->page_selected = FALSE;
+
+} /* ctk_display_config_unselected() */
+
+
+
+/** ctk_display_config_selected() ***********************************
+ *
+ * Called when display config page is selected.
+ *
+ **/
+
+void ctk_display_config_selected(GtkWidget *widget) {
+ CtkDisplayConfig *ctk_object=CTK_DISPLAY_CONFIG(widget);
+
+ ctk_object->page_selected = TRUE;
+
+ /* Handle case where a layout reset is required but we could
+ * not notify the user since the X server display configuration
+ * page was not selected
+ */
+ if (ctk_object->reset_required) {
+ force_layout_reset(ctk_object);
+ }
+
+} /* ctk_display_config_selected() */
diff --git a/src/gtk+-2.x/ctkdisplayconfig.h b/src/gtk+-2.x/ctkdisplayconfig.h
index 3a8348d..e87e8ab 100644
--- a/src/gtk+-2.x/ctkdisplayconfig.h
+++ b/src/gtk+-2.x/ctkdisplayconfig.h
@@ -60,6 +60,7 @@ typedef struct _CtkDisplayConfig
NvCtrlAttributeHandle *handle;
CtkConfig *ctk_config;
+ gboolean page_selected; /* Is the display config page selected in the UI */
/* Layout */
nvLayoutPtr layout;
@@ -173,6 +174,12 @@ typedef struct _CtkDisplayConfig
/* Buttons */
GtkWidget *btn_apply;
gboolean apply_possible; /* True if all modifications are applicable */
+
+ gboolean reset_required; /* Reser required to apply */
+ gboolean forced_reset_allowed; /* OK to reset layout w/o user input */
+ gboolean notify_user_of_reset; /* User was notified of reset requirement */
+ gboolean ignore_reset_events; /* Ignore reset-causing events */
+
int cur_screen_pos[2]; /* Keep track of the selected X screen's position */
GtkWidget *btn_save;
@@ -198,6 +205,10 @@ GtkWidget* ctk_display_config_new (NvCtrlAttributeHandle *,
GtkTextBuffer *ctk_display_config_create_help(GtkTextTagTable *,
CtkDisplayConfig *);
+void ctk_display_config_selected(GtkWidget *);
+void ctk_display_config_unselected(GtkWidget *);
+
+
G_END_DECLS
#endif /* __CTK_DISPLAYCONFIG_H__ */
diff --git a/src/gtk+-2.x/ctkdisplaydevice-crt.c b/src/gtk+-2.x/ctkdisplaydevice-crt.c
index 4f391c7..991875b 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-crt.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-crt.c
@@ -92,6 +92,13 @@ static void ctk_display_device_crt_finalize(
{
CtkDisplayDeviceCrt *ctk_display_device_crt = CTK_DISPLAY_DEVICE_CRT(object);
g_free(ctk_display_device_crt->name);
+ g_signal_handlers_disconnect_matched(ctk_display_device_crt->ctk_event,
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ (gpointer) ctk_display_device_crt);
}
/*
@@ -115,6 +122,7 @@ GtkWidget* ctk_display_device_crt_new(NvCtrlAttributeHandle *handle,
GtkWidget *alignment;
object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_CRT, NULL);
+ if (!object) return NULL;
ctk_display_device_crt = CTK_DISPLAY_DEVICE_CRT(object);
ctk_display_device_crt->handle = handle;
diff --git a/src/gtk+-2.x/ctkdisplaydevice-dfp.c b/src/gtk+-2.x/ctkdisplaydevice-dfp.c
index 13da164..86c2a66 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-dfp.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-dfp.c
@@ -169,6 +169,13 @@ static void ctk_display_device_dfp_finalize(
{
CtkDisplayDeviceDfp *ctk_display_device_dfp = CTK_DISPLAY_DEVICE_DFP(object);
g_free(ctk_display_device_dfp->name);
+ g_signal_handlers_disconnect_matched(ctk_display_device_dfp->ctk_event,
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ (gpointer) ctk_display_device_dfp);
}
@@ -199,9 +206,11 @@ GtkWidget* ctk_display_device_dfp_new(NvCtrlAttributeHandle *handle,
GtkWidget *table;
object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_DFP, NULL);
+ if (!object) return NULL;
ctk_display_device_dfp = CTK_DISPLAY_DEVICE_DFP(object);
ctk_display_device_dfp->handle = handle;
+ ctk_display_device_dfp->ctk_event = ctk_event;
ctk_display_device_dfp->ctk_config = ctk_config;
ctk_display_device_dfp->display_device_mask = display_device_mask;
ctk_display_device_dfp->name = g_strdup(name);
diff --git a/src/gtk+-2.x/ctkdisplaydevice-tv.c b/src/gtk+-2.x/ctkdisplaydevice-tv.c
index 4db531c..12773e6 100644
--- a/src/gtk+-2.x/ctkdisplaydevice-tv.c
+++ b/src/gtk+-2.x/ctkdisplaydevice-tv.c
@@ -131,6 +131,13 @@ static void ctk_display_device_tv_finalize(
{
CtkDisplayDeviceTv *ctk_display_device_tv = CTK_DISPLAY_DEVICE_TV(object);
g_free(ctk_display_device_tv->name);
+ g_signal_handlers_disconnect_matched(ctk_display_device_tv->ctk_event,
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ (gpointer) ctk_display_device_tv);
}
@@ -156,6 +163,7 @@ GtkWidget* ctk_display_device_tv_new(NvCtrlAttributeHandle *handle,
object = g_object_new(CTK_TYPE_DISPLAY_DEVICE_TV, NULL);
+ if (!object) return NULL;
ctk_display_device_tv = CTK_DISPLAY_DEVICE_TV(object);
ctk_display_device_tv->handle = handle;
diff --git a/src/gtk+-2.x/ctkdisplaylayout.c b/src/gtk+-2.x/ctkdisplaylayout.c
index 3f38c1e..6d8b620 100644
--- a/src/gtk+-2.x/ctkdisplaylayout.c
+++ b/src/gtk+-2.x/ctkdisplaylayout.c
@@ -2372,7 +2372,8 @@ GtkWidget* ctk_display_layout_new(NvCtrlAttributeHandle *handle,
pango_font_description_set_family(font_description, "Sans");
pango_font_description_set_weight(font_description, PANGO_WEIGHT_BOLD);
- pango_layout_set_font_description(ctk_object->pango_layout, font_description);
+ pango_layout_set_font_description(ctk_object->pango_layout,
+ font_description);
/* Setup colors */
@@ -2404,23 +2405,28 @@ GtkWidget* ctk_display_layout_new(NvCtrlAttributeHandle *handle,
GDK_POINTER_MOTION_MASK);
g_signal_connect (G_OBJECT (tmp), "expose_event",
- G_CALLBACK (expose_event_callback), (gpointer)(ctk_object));
+ G_CALLBACK (expose_event_callback),
+ (gpointer)(ctk_object));
g_signal_connect (G_OBJECT (tmp), "configure_event",
- G_CALLBACK (configure_event_callback), (gpointer)(ctk_object));
+ G_CALLBACK (configure_event_callback),
+ (gpointer)(ctk_object));
g_signal_connect (G_OBJECT (tmp), "motion_notify_event",
- G_CALLBACK (motion_event_callback), (gpointer)(ctk_object));
+ G_CALLBACK (motion_event_callback),
+ (gpointer)(ctk_object));
g_signal_connect (G_OBJECT (tmp), "button_press_event",
- G_CALLBACK (button_press_event_callback), (gpointer)(ctk_object));
+ G_CALLBACK (button_press_event_callback),
+ (gpointer)(ctk_object));
g_signal_connect (G_OBJECT (tmp), "button_release_event",
- G_CALLBACK (button_release_event_callback), (gpointer)(ctk_object));
+ G_CALLBACK (button_release_event_callback),
+ (gpointer)(ctk_object));
GTK_WIDGET_SET_FLAGS(tmp, GTK_DOUBLE_BUFFERED);
- ctk_object->drawing_area = tmp;
+ ctk_object->drawing_area = tmp;
gtk_widget_set_size_request(tmp, width, height);
@@ -2445,6 +2451,26 @@ GtkWidget* ctk_display_layout_new(NvCtrlAttributeHandle *handle,
+/** get_widget_fg_gc() ***********************************************
+ *
+ * Returns the foreground graphics context of the given widget. If
+ * this function returns NULL, then drawing on this widget is not
+ * currently possible and should be avoided.
+ *
+ **/
+
+static GdkGC *get_widget_fg_gc(GtkWidget *widget)
+{
+ GtkStyle *style = gtk_widget_get_style(widget);
+
+ if (!style) return NULL;
+
+ return style->fg_gc[GTK_WIDGET_STATE(widget)];
+
+} /* get_widget_fg_gc() */
+
+
+
/** do_swap() ********************************************************
*
* Preforms a swap from the back buffer if one is needed.
@@ -2453,10 +2479,13 @@ GtkWidget* ctk_display_layout_new(NvCtrlAttributeHandle *handle,
static void do_swap(CtkDisplayLayout *ctk_object)
{
- if (ctk_object->need_swap) {
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
+
+ if (ctk_object->need_swap && drawing_area->window && fg_gc) {
- gdk_draw_pixmap(ctk_object->drawing_area->window,
- ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
+ gdk_draw_pixmap(drawing_area->window,
+ fg_gc,
ctk_object->pixmap,
0,0,
0,0,
@@ -2482,16 +2511,18 @@ static void draw_rect(CtkDisplayLayout *ctk_object,
GdkColor *color,
int fill)
{
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
+
int w = (int)(ctk_object->scale * (dim[X] + dim[W])) - (int)(ctk_object->scale * (dim[X]));
int h = (int)(ctk_object->scale * (dim[Y] + dim[H])) - (int)(ctk_object->scale * (dim[Y]));
/* Setup color to use */
- gdk_gc_set_rgb_fg_color(ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE (ctk_object->drawing_area)],
- color);
+ gdk_gc_set_rgb_fg_color(fg_gc, color);
/* Draw the rectangle */
gdk_draw_rectangle(ctk_object->pixmap,
- ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE (ctk_object->drawing_area)],
+ fg_gc,
fill,
ctk_object->img_dim[X] + ctk_object->scale * dim[X],
ctk_object->img_dim[Y] + ctk_object->scale * dim[Y],
@@ -2517,8 +2548,8 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object,
const char *str_1,
const char *str_2)
{
- GdkGC *gdk_gc;
- GtkWidget *drawing_area;
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
char *str;
int txt_w;
@@ -2529,9 +2560,6 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object,
int draw_1 = 0;
int draw_2 = 0;
- drawing_area = ctk_object->drawing_area;
- gdk_gc = drawing_area->style->fg_gc[GTK_WIDGET_STATE(drawing_area)];
-
if (str_1) {
pango_layout_set_text(ctk_object->pango_layout, str_1, -1);
pango_layout_get_pixel_size(ctk_object->pango_layout, &txt_w, &txt_h);
@@ -2572,9 +2600,10 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object,
txt_y1 = ctk_object->scale*(dim[Y] + dim[H] / 2) - (txt_h / 2);
/* Write name */
- gdk_gc_set_rgb_fg_color(gdk_gc, color);
+ gdk_gc_set_rgb_fg_color(fg_gc, color);
- gdk_draw_layout(ctk_object->pixmap, gdk_gc,
+ gdk_draw_layout(ctk_object->pixmap,
+ fg_gc,
ctk_object->img_dim[X] + txt_x1,
ctk_object->img_dim[Y] + txt_y1,
ctk_object->pango_layout);
@@ -2590,9 +2619,10 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object,
txt_y2 = ctk_object->scale*(dim[Y] + dim[H] / 2) - (txt_h / 2);
/* Write dimensions */
- gdk_gc_set_rgb_fg_color(gdk_gc, color);
+ gdk_gc_set_rgb_fg_color(fg_gc, color);
- gdk_draw_layout(ctk_object->pixmap, gdk_gc,
+ gdk_draw_layout(ctk_object->pixmap,
+ fg_gc,
ctk_object->img_dim[X] + txt_x2,
ctk_object->img_dim[Y] + txt_y2,
ctk_object->pango_layout);
@@ -2610,9 +2640,10 @@ static void draw_rect_strs(CtkDisplayLayout *ctk_object,
txt_y = ctk_object->scale*(dim[Y] + dim[H] / 2) - (txt_h / 2);
/* Write both */
- gdk_gc_set_rgb_fg_color(gdk_gc, color);
+ gdk_gc_set_rgb_fg_color(fg_gc, color);
- gdk_draw_layout(ctk_object->pixmap, gdk_gc,
+ gdk_draw_layout(ctk_object->pixmap,
+ fg_gc,
ctk_object->img_dim[X] + txt_x,
ctk_object->img_dim[Y] + txt_y,
ctk_object->pango_layout);
@@ -2634,27 +2665,29 @@ static void draw_display(CtkDisplayLayout *ctk_object,
nvDisplayPtr display)
{
nvModePtr mode;
- int color;
+ int base_color_idx;
+ int color_idx;
char *tmp_str;
if (!display || !(display->cur_mode)) {
return;
}
- mode = display->cur_mode;
- color = NUM_COLORS_PER_PALETTE * NvCtrlGetTargetId(display->gpu->handle);
+ mode = display->cur_mode;
+ base_color_idx =
+ NUM_COLORS_PER_PALETTE * NvCtrlGetTargetId(display->gpu->handle);
/* Draw panning */
- draw_rect(ctk_object, mode->pan,
- &(ctk_object->color_palettes[color +((mode->modeline)?BG_PAN_ON:BG_PAN_OFF)]),
+ color_idx = base_color_idx + ((mode->modeline) ? BG_PAN_ON : BG_PAN_OFF);
+ draw_rect(ctk_object, mode->pan, &(ctk_object->color_palettes[color_idx]),
1);
draw_rect(ctk_object, mode->pan, &(ctk_object->fg_color), 0);
/* Draw viewport */
- draw_rect(ctk_object, mode->dim,
- &(ctk_object->color_palettes[color +((mode->modeline)?BG_SCR_ON:BG_SCR_OFF)]),
+ 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]),
1);
draw_rect(ctk_object, mode->dim, &(ctk_object->fg_color), 0);
@@ -2686,21 +2719,22 @@ static void draw_display(CtkDisplayLayout *ctk_object,
static void draw_layout(CtkDisplayLayout *ctk_object)
{
- int z;
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
+
GdkColor bg_color; /* Background color */
GdkColor bd_color; /* Border color */
nvGpuPtr gpu;
nvScreenPtr screen;
+ int z;
/* Draw the metamode's effective size */
gdk_color_parse("#888888", &bg_color);
gdk_color_parse("#777777", &bd_color);
- gdk_gc_set_line_attributes
- (ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_NOT_LAST,
- GDK_JOIN_ROUND);
+ gdk_gc_set_line_attributes(fg_gc, 1, GDK_LINE_ON_OFF_DASH,
+ GDK_CAP_NOT_LAST, GDK_JOIN_ROUND);
for (gpu = ctk_object->layout->gpus; gpu; gpu = gpu->next) {
for (screen = gpu->screens; screen; screen = screen->next) {
@@ -2710,10 +2744,8 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
}
}
- gdk_gc_set_line_attributes
- (ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,
- GDK_JOIN_ROUND);
+ gdk_gc_set_line_attributes(fg_gc, 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST,
+ GDK_JOIN_ROUND);
/* Draw display devices from back to front */
@@ -2725,7 +2757,6 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
/* Hilite the selected display device */
if (ctk_object->Zselected && ctk_object->Zcount) {
- GtkWidget *widget = ctk_object->drawing_area;
int w, h;
int size; /* Hilite line size */
int offset; /* Hilite box offset */
@@ -2738,8 +2769,7 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
h = (int)(ctk_object->scale * (dim[Y] + dim[H])) - (int)(ctk_object->scale * (dim[Y]));
/* Setup color to use */
- gdk_gc_set_rgb_fg_color(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &(ctk_object->select_color));
+ gdk_gc_set_rgb_fg_color(fg_gc, &(ctk_object->select_color));
/* If dislay is too small, just color the whole thing */
size = 3;
@@ -2750,19 +2780,19 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
draw_rect(ctk_object, dim, &(ctk_object->fg_color), 0);
} else {
- gdk_gc_set_line_attributes(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- size, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gdk_gc_set_line_attributes(fg_gc, size, GDK_LINE_SOLID,
+ GDK_CAP_ROUND, GDK_JOIN_ROUND);
gdk_draw_rectangle(ctk_object->pixmap,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ fg_gc,
0,
ctk_object->img_dim[X] +(ctk_object->scale * dim[X]) +offset,
ctk_object->img_dim[Y] +(ctk_object->scale * dim[Y]) +offset,
w -(2 * offset),
h -(2 * offset));
- gdk_gc_set_line_attributes(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- 1, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
+ gdk_gc_set_line_attributes(fg_gc, 1, GDK_LINE_SOLID, GDK_CAP_ROUND,
+ GDK_JOIN_ROUND);
}
@@ -2811,46 +2841,44 @@ static void draw_layout(CtkDisplayLayout *ctk_object)
static void clear_layout(CtkDisplayLayout *ctk_object)
{
- GtkWidget *widget = ctk_object->drawing_area;
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
GdkColor color;
-
/* Clear to background color */
- gdk_gc_set_rgb_fg_color(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &(ctk_object->bg_color));
+ gdk_gc_set_rgb_fg_color(fg_gc, &(ctk_object->bg_color));
+
gdk_draw_rectangle(ctk_object->pixmap,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ fg_gc,
TRUE,
2,
2,
- widget->allocation.width -4,
- widget->allocation.height -4);
+ drawing_area->allocation.width -4,
+ drawing_area->allocation.height -4);
/* Add white trim */
gdk_color_parse("white", &color);
- gdk_gc_set_rgb_fg_color(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &color);
+ gdk_gc_set_rgb_fg_color(fg_gc, &color);
gdk_draw_rectangle(ctk_object->pixmap,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ fg_gc,
FALSE,
1,
1,
- widget->allocation.width -3,
- widget->allocation.height -3);
+ drawing_area->allocation.width -3,
+ drawing_area->allocation.height -3);
/* Add layout border */
- gdk_gc_set_rgb_fg_color(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &(ctk_object->fg_color));
+ gdk_gc_set_rgb_fg_color(fg_gc, &(ctk_object->fg_color));
gdk_draw_rectangle(ctk_object->pixmap,
- widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+ fg_gc,
FALSE,
0,
0,
- widget->allocation.width -1,
- widget->allocation.height -1);
+ drawing_area->allocation.width -1,
+ drawing_area->allocation.height -1);
ctk_object->need_swap = 1;
@@ -2866,21 +2894,20 @@ static void clear_layout(CtkDisplayLayout *ctk_object)
static void draw_all(CtkDisplayLayout *ctk_object)
{
- GdkGCValues old_gc_values;
- GtkWidget *widget = ctk_object->drawing_area;
-
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
+ GdkGCValues old_gc_values;
+
+ if (!fg_gc) return;
/* Redraw everything */
- gdk_gc_get_values(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &old_gc_values);
+ gdk_gc_get_values(fg_gc, &old_gc_values);
clear_layout(ctk_object);
draw_layout(ctk_object);
- gdk_gc_set_values(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &old_gc_values,
- GDK_GC_FOREGROUND);
+ gdk_gc_set_values(fg_gc, &old_gc_values, GDK_GC_FOREGROUND);
} /* draw_all() */
@@ -3290,6 +3317,8 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
nvDisplayPtr relative_to,
int x, int y)
{
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
GdkGCValues old_gc_values;
int modified = 0;
nvLayoutPtr layout = ctk_object->layout;
@@ -3301,11 +3330,11 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
/* Backup the foreground color and clear the layout */
- gdk_gc_get_values
- (ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- &old_gc_values);
-
- clear_layout(ctk_object);
+ if (fg_gc) {
+ gdk_gc_get_values(fg_gc, &old_gc_values);
+
+ clear_layout(ctk_object);
+ }
/* XXX When configuring a relative position, make sure
@@ -3381,13 +3410,13 @@ void ctk_display_layout_set_display_position(CtkDisplayLayout *ctk_object,
/* Redraw the layout and reset the foreground color */
- draw_layout(ctk_object);
-
- gdk_gc_set_values
- (ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- &old_gc_values, GDK_GC_FOREGROUND);
+ if (fg_gc) {
+ draw_layout(ctk_object);
- do_swap(ctk_object);
+ gdk_gc_set_values(fg_gc, &old_gc_values, GDK_GC_FOREGROUND);
+
+ do_swap(ctk_object);
+ }
} /* ctk_display_layout_set_display_position() */
@@ -3403,6 +3432,8 @@ void ctk_display_layout_set_display_panning(CtkDisplayLayout *ctk_object,
nvDisplayPtr display,
int width, int height)
{
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
GdkGCValues old_gc_values;
int modified = 0;
@@ -3411,10 +3442,11 @@ void ctk_display_layout_set_display_panning(CtkDisplayLayout *ctk_object,
/* Backup the foreground color */
- gdk_gc_get_values(ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- &old_gc_values);
+ if (fg_gc) {
+ gdk_gc_get_values(fg_gc, &old_gc_values);
- clear_layout(ctk_object);
+ clear_layout(ctk_object);
+ }
/* Change the panning */
@@ -3434,24 +3466,26 @@ void ctk_display_layout_set_display_panning(CtkDisplayLayout *ctk_object,
ctk_object->modified_callback_data);
}
- draw_layout(ctk_object);
+ /* Redraw layout and reset the foreground color */
+ if (fg_gc) {
+ draw_layout(ctk_object);
- /* Reset the foreground color */
- gdk_gc_set_values(ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- &old_gc_values,
- GDK_GC_FOREGROUND);
-
- do_swap(ctk_object);
+ gdk_gc_set_values(fg_gc, &old_gc_values, GDK_GC_FOREGROUND);
+ do_swap(ctk_object);
+ }
} /* ctk_display_layout_set_display_panning() */
+
+
/** ctk_display_layout_select_display() ***********************
*
* Updates the currently selected display.
*
**/
+
void ctk_display_layout_select_display(CtkDisplayLayout *ctk_object,
nvDisplayPtr display)
{
@@ -3462,8 +3496,11 @@ void ctk_display_layout_select_display(CtkDisplayLayout *ctk_object,
/* Select the new topmost display */
select_display(ctk_object, ctk_object->Zorder[0]);
}
+
} /* ctk_display_layout_select_display() */
+
+
/** ctk_display_layout_update_display_count() ************************
*
* Updates the number of displays shown in the layout by re-building
@@ -3479,6 +3516,7 @@ void ctk_display_layout_update_display_count(CtkDisplayLayout *ctk_object,
/* Select the previously selected display */
ctk_display_layout_select_display(ctk_object, display);
+
} /* ctk_display_layout_update_display_count() */
@@ -3514,27 +3552,22 @@ void ctk_display_layout_set_screen_position(CtkDisplayLayout *ctk_object,
nvScreenPtr relative_to,
int x, int y)
{
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
GdkGCValues old_gc_values;
int modified = 0;
nvLayoutPtr layout = ctk_object->layout;
nvGpuPtr gpu;
- int draw;
+
if (!screen) return;
if (position_type != CONF_ADJ_ABSOLUTE && !relative_to) return;
- /* If there is no GC for the drawing area, don't draw */
- draw = ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)] ?
- 1 : 0;
-
-
/* Backup the foreground color and clear the layout */
- if (draw) {
- gdk_gc_get_values
- (ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- &old_gc_values);
+ if (fg_gc) {
+ gdk_gc_get_values(fg_gc, &old_gc_values);
clear_layout(ctk_object);
}
@@ -3634,12 +3667,10 @@ void ctk_display_layout_set_screen_position(CtkDisplayLayout *ctk_object,
/* Redraw the layout and reset the foreground color */
- if (draw) {
+ if (fg_gc) {
draw_layout(ctk_object);
- gdk_gc_set_values
- (ctk_object->drawing_area->style->fg_gc[GTK_WIDGET_STATE(ctk_object->drawing_area)],
- &old_gc_values, GDK_GC_FOREGROUND);
+ gdk_gc_set_values(fg_gc, &old_gc_values, GDK_GC_FOREGROUND);
do_swap(ctk_object);
}
@@ -3742,14 +3773,16 @@ static gboolean
motion_event_callback(GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
CtkDisplayLayout *ctk_object = CTK_DISPLAY_LAYOUT(data);
- GdkGCValues old_gc_values;
+ GtkWidget *drawing_area = ctk_object->drawing_area;
+ GdkGC *fg_gc = get_widget_fg_gc(drawing_area);
+ GdkGCValues old_gc_values;
static int init = 1;
static int __modify_panning;
if (init) {
init = 0;
- __modify_panning = (event->state & ShiftMask)?1:0;
+ __modify_panning = (event->state & ShiftMask) ? 1 : 0;
}
@@ -3767,8 +3800,7 @@ motion_event_callback(GtkWidget *widget, GdkEventMotion *event, gpointer data)
/* Backup the foreground color */
- gdk_gc_get_values(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &old_gc_values);
+ gdk_gc_get_values(fg_gc, &old_gc_values);
/* Modify screen layout */
@@ -3783,8 +3815,8 @@ motion_event_callback(GtkWidget *widget, GdkEventMotion *event, gpointer data)
clear_layout(ctk_object);
/* Swap between panning and moving */
- if (__modify_panning != (event->state & ShiftMask)?1:0) {
- __modify_panning = (event->state & ShiftMask)?1:0;
+ if (__modify_panning != ((event->state & ShiftMask) ? 1 : 0)) {
+ __modify_panning = ((event->state & ShiftMask) ? 1 : 0);
sync_modify(ctk_object);
}
if (!(event->state & ShiftMask) || !ctk_object->advanced_mode) {
@@ -3801,7 +3833,6 @@ motion_event_callback(GtkWidget *widget, GdkEventMotion *event, gpointer data)
draw_layout(ctk_object);
-
/* Update the tooltip under the mouse */
} else {
char *tip =
@@ -3823,9 +3854,7 @@ motion_event_callback(GtkWidget *widget, GdkEventMotion *event, gpointer data)
/* Reset the foreground color */
- gdk_gc_set_values(widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
- &old_gc_values,
- GDK_GC_FOREGROUND);
+ gdk_gc_set_values(fg_gc, &old_gc_values, GDK_GC_FOREGROUND);
/* Refresh GUI */
@@ -3900,9 +3929,9 @@ button_press_event_callback(GtkWidget *widget, GdkEventButton *event,
time = event->time;
}
-
/* Redraw everything */
draw_all(ctk_object);
+
break;
default:
diff --git a/src/gtk+-2.x/ctkdropdownmenu.c b/src/gtk+-2.x/ctkdropdownmenu.c
index 3fea606..3fca0b7 100644
--- a/src/gtk+-2.x/ctkdropdownmenu.c
+++ b/src/gtk+-2.x/ctkdropdownmenu.c
@@ -134,12 +134,17 @@ GtkWidget* ctk_drop_down_menu_new(guint flags)
d->values = NULL;
d->num_entries = 0;
- d->menu = gtk_menu_new();
d->option_menu = gtk_option_menu_new();
-
+ d->menu = gtk_menu_new();
+
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(d->option_menu), d->menu);
+
gtk_box_set_spacing(GTK_BOX(d), 0);
gtk_box_pack_start(GTK_BOX(d), d->option_menu, FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(d->option_menu), "changed",
+ G_CALLBACK(changed), (gpointer) d);
+
return GTK_WIDGET(d);
} /* ctk_drop_down_menu_new() */
@@ -158,6 +163,8 @@ void ctk_drop_down_menu_reset(CtkDropDownMenu *d)
d->num_entries = 0;
d->menu = gtk_menu_new();
+
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(d->option_menu), d->menu);
} /* ctk_drop_down_menu_reset() */
@@ -168,9 +175,9 @@ void ctk_drop_down_menu_reset(CtkDropDownMenu *d)
* menu
*/
-void ctk_drop_down_menu_append_item(CtkDropDownMenu *d,
- const gchar *name,
- const gint value)
+GtkWidget *ctk_drop_down_menu_append_item(CtkDropDownMenu *d,
+ const gchar *name,
+ const gint value)
{
GtkWidget *menu_item, *label, *alignment;
gchar *str;
@@ -197,30 +204,14 @@ void ctk_drop_down_menu_append_item(CtkDropDownMenu *d,
d->values[d->num_entries].value = value;
d->num_entries++;
+
+ return label;
} /* ctk_drop_down_menu_append_item() */
/*
- * ctk_drop_down_menu_finalize() - to be called once all menu entries
- * have been added.
- */
-
-void ctk_drop_down_menu_finalize(CtkDropDownMenu *d)
-{
- gtk_option_menu_set_menu(GTK_OPTION_MENU(d->option_menu), d->menu);
-
- g_signal_connect(G_OBJECT(d->option_menu), "changed",
- G_CALLBACK(changed), (gpointer) d);
-
- gtk_widget_show_all(GTK_WIDGET(d));
-
-} /* ctk_drop_down_menu_finalize() */
-
-
-
-/*
* ctk_drop_down_menu_get_current_value() - return the current value
* selected in the drop down menu.
*/
diff --git a/src/gtk+-2.x/ctkdropdownmenu.h b/src/gtk+-2.x/ctkdropdownmenu.h
index b1ee87d..b0c544d 100644
--- a/src/gtk+-2.x/ctkdropdownmenu.h
+++ b/src/gtk+-2.x/ctkdropdownmenu.h
@@ -85,10 +85,9 @@ struct _CtkDropDownMenuClass
GType ctk_drop_down_menu_get_type (void) G_GNUC_CONST;
GtkWidget* ctk_drop_down_menu_new (guint flags);
-void ctk_drop_down_menu_append_item (CtkDropDownMenu *d,
+GtkWidget* ctk_drop_down_menu_append_item (CtkDropDownMenu *d,
const gchar *name,
const gint value);
-void ctk_drop_down_menu_finalize (CtkDropDownMenu *d);
gint ctk_drop_down_menu_get_current_value (CtkDropDownMenu *d);
void ctk_drop_down_menu_set_current_value (CtkDropDownMenu *d,
gint value);
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index 090f77d..1e056a7 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -254,7 +254,12 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_GVO_COMPOSITE_ALPHA_KEY);
MAKE_SIGNAL(NV_CTRL_GVO_COMPOSITE_NUM_KEY_RANGES);
MAKE_SIGNAL(NV_CTRL_NOTEBOOK_DISPLAY_CHANGE_LID_EVENT);
+ MAKE_SIGNAL(NV_CTRL_MODE_SET_EVENT);
+ MAKE_SIGNAL(NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE);
MAKE_SIGNAL(NV_CTRL_DISPLAYPORT_LINK_RATE);
+ MAKE_SIGNAL(NV_CTRL_STEREO_EYES_EXCHANGE);
+ MAKE_SIGNAL(NV_CTRL_NO_SCANOUT);
+ MAKE_SIGNAL(NV_CTRL_GVO_CSC_CHANGED_EVENT);
#undef MAKE_SIGNAL
@@ -265,7 +270,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DISPLAYPORT_LINK_RATE
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GVO_CSC_CHANGED_EVENT
#warning "There are attributes that do not emit signals!"
#endif
diff --git a/src/gtk+-2.x/ctkframelock.c b/src/gtk+-2.x/ctkframelock.c
index 81aa319..66705fc 100644
--- a/src/gtk+-2.x/ctkframelock.c
+++ b/src/gtk+-2.x/ctkframelock.c
@@ -696,13 +696,13 @@ static GtkWidget *create_enable_confirm_dialog(CtkFramelock *ctk_framelock)
GTK_WINDOW(gtk_widget_get_parent(GTK_WIDGET(ctk_framelock))),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT
| GTK_DIALOG_NO_SEPARATOR,
- GTK_STOCK_OK,
+ GTK_STOCK_YES,
GTK_RESPONSE_ACCEPT,
NULL);
ctk_framelock->enable_confirm_cancel_button =
gtk_dialog_add_button(GTK_DIALOG(dialog),
- GTK_STOCK_CANCEL,
+ GTK_STOCK_NO,
GTK_RESPONSE_REJECT);
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
@@ -2755,7 +2755,7 @@ static void update_enable_confirm_text(CtkFramelock *ctk_framelock)
gchar *str;
str = g_strdup_printf("Frame Lock has been enabled but no server\n"
"device was selected. Would you like to keep\n"
- "the current settings?\n"
+ "Frame Lock enabled on the selected devices?\n"
"\n"
"Disabling Frame Lock in %d seconds...",
ctk_framelock->enable_confirm_countdown);
diff --git a/src/gtk+-2.x/ctkgvo-csc.c b/src/gtk+-2.x/ctkgvo-csc.c
index 16bca87..341b26f 100644
--- a/src/gtk+-2.x/ctkgvo-csc.c
+++ b/src/gtk+-2.x/ctkgvo-csc.c
@@ -28,14 +28,14 @@
#include <string.h>
#include "ctkbanner.h"
-
-#include "ctkgvo-csc.h"
-
#include "ctkconfig.h"
#include "ctkhelp.h"
-
#include "ctkdropdownmenu.h"
+#include "ctkgvo-csc.h"
+
+#include "msg.h"
+
/*
* The CtkGvoCsc widget is used to provide a way for configuring
* custom Color Space Conversion Matrices, Offsets, and Scale Factors
@@ -110,6 +110,10 @@ static void set_apply_button_senstive (CtkGvoCsc *ctk_gvo_csc);
static void apply_csc_values (CtkGvoCsc *ctk_gvo_csc);
+static void gvo_csc_event_received (GtkObject *object,
+ gpointer arg1,
+ gpointer user_data);
+
static GtkWidget *build_opengl_only_msg (void);
/*
@@ -137,8 +141,9 @@ static const char * __override_help =
"custom CSC.";
static const char * __initialize_help =
-"The Initialize Color Space Conversion dropdown allows you to select between "
-"some standard CSC configurations.";
+"The Initialize Color Space Conversion drop down menu, when selected, "
+"populates the Color Space Conversion Matrix, Offset, and Scale with the "
+"values from the selected standard.";
static const char * __csc_help =
"The color space conversion matrix defines the paramaters used for "
@@ -236,6 +241,7 @@ GtkWidget* ctk_gvo_csc_new(NvCtrlAttributeHandle *handle,
ctk_gvo_csc = CTK_GVO_CSC(object);
ctk_gvo_csc->handle = handle;
ctk_gvo_csc->ctk_config = ctk_config;
+ ctk_gvo_csc->ctk_event = ctk_event;
ctk_gvo_csc->gvo_parent = gvo_parent;
ctk_gvo_csc->caps = caps;
@@ -355,8 +361,7 @@ GtkWidget* ctk_gvo_csc_new(NvCtrlAttributeHandle *handle,
CSC_STANDARD_IDENTITY_STRING,
CSC_STANDARD_IDENTITY);
- ctk_drop_down_menu_finalize
- (CTK_DROP_DOWN_MENU(ctk_gvo_csc->initializeDropDown));
+ gtk_widget_show_all(ctk_gvo_csc->initializeDropDown);
gtk_box_pack_start(GTK_BOX(hbox),
ctk_gvo_csc->initializeDropDown,
@@ -364,6 +369,10 @@ GtkWidget* ctk_gvo_csc_new(NvCtrlAttributeHandle *handle,
FALSE, // fill
5); // padding
+ ctk_drop_down_menu_set_current_value
+ (CTK_DROP_DOWN_MENU(ctk_gvo_csc->initializeDropDown),
+ CSC_STANDARD_ITU_601);
+
g_signal_connect(G_OBJECT(ctk_gvo_csc->initializeDropDown), "changed",
G_CALLBACK(initialize_csc_dropdown_changed),
@@ -645,6 +654,18 @@ GtkWidget* ctk_gvo_csc_new(NvCtrlAttributeHandle *handle,
override_state_toggled(ctk_gvo_csc, override);
+ /* Listen to server events */
+
+ g_signal_connect(G_OBJECT(ctk_gvo_csc->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_GVO_CSC_CHANGED_EVENT),
+ G_CALLBACK(gvo_csc_event_received),
+ (gpointer) ctk_gvo_csc);
+
+ g_signal_connect(G_OBJECT(ctk_gvo_csc->ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_GVO_OVERRIDE_HW_CSC),
+ G_CALLBACK(gvo_csc_event_received),
+ (gpointer) ctk_gvo_csc);
+
/* show the page */
gtk_widget_show_all(GTK_WIDGET(object));
@@ -1016,6 +1037,114 @@ static void apply_csc_values(CtkGvoCsc *ctk_gvo_csc)
} /* apply_csc_values() */
+
+/*
+ * GVO CSC event handler.
+ */
+
+static void gvo_csc_event_received(GtkObject *object,
+ gpointer arg1,
+ gpointer user_data)
+{
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+ CtkGvoCsc *ctk_gvo_csc = CTK_GVO_CSC(user_data);
+ GtkWidget *widget;
+ gint attribute = event_struct->attribute;
+ gint value = event_struct->value;
+ ReturnStatus ret;
+
+ float newCSCMatrix[3][3];
+ float newCSCOffset[3];
+ float newCSCScale[3];
+ int row, column;
+
+
+ switch (attribute) {
+
+ case NV_CTRL_GVO_CSC_CHANGED_EVENT:
+
+ /* Re-query the GVO CSC matrix */
+
+ ret = NvCtrlGetGvoColorConversion(ctk_gvo_csc->handle,
+ newCSCMatrix,
+ newCSCOffset,
+ newCSCScale);
+ if (ret == NvCtrlSuccess) {
+
+ for (row = 0; row < 3; row++) {
+ for (column = 0; column < 3; column++) {
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_gvo_csc->matrixWidget[row][column]),
+ G_CALLBACK(spin_button_value_changed),
+ (gpointer) ctk_gvo_csc);
+ ctk_gvo_csc->matrix[row][column] = newCSCMatrix[row][column];
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON(ctk_gvo_csc->matrixWidget[row][column]),
+ ctk_gvo_csc->matrix[row][column]);
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_gvo_csc->matrixWidget[row][column]),
+ G_CALLBACK(spin_button_value_changed),
+ (gpointer) ctk_gvo_csc);
+ }
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_gvo_csc->offsetWidget[row]),
+ G_CALLBACK(spin_button_value_changed),
+ (gpointer) ctk_gvo_csc);
+ ctk_gvo_csc->offset[row] = newCSCOffset[row];
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON(ctk_gvo_csc->offsetWidget[row]),
+ ctk_gvo_csc->offset[row]);
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_gvo_csc->offsetWidget[row]),
+ G_CALLBACK(spin_button_value_changed),
+ (gpointer) ctk_gvo_csc);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(ctk_gvo_csc->scaleWidget[row]),
+ G_CALLBACK(spin_button_value_changed),
+ (gpointer) ctk_gvo_csc);
+ ctk_gvo_csc->scale[row] = newCSCScale[row];
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON(ctk_gvo_csc->scaleWidget[row]),
+ ctk_gvo_csc->scale[row]);
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(ctk_gvo_csc->scaleWidget[row]),
+ G_CALLBACK(spin_button_value_changed),
+ (gpointer) ctk_gvo_csc);
+ }
+ }
+
+ gtk_widget_set_sensitive(ctk_gvo_csc->applyButton, FALSE);
+ break;
+
+ case NV_CTRL_GVO_OVERRIDE_HW_CSC:
+ widget = ctk_gvo_csc->overrideButton;
+
+ g_signal_handlers_block_by_func(G_OBJECT(widget),
+ G_CALLBACK(override_button_toggled),
+ (gpointer) ctk_gvo_csc);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), value);
+ override_state_toggled(ctk_gvo_csc, value);
+
+ gtk_widget_set_sensitive(ctk_gvo_csc->applyButton, FALSE);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(widget),
+ G_CALLBACK(override_button_toggled),
+ (gpointer) ctk_gvo_csc);
+ break;
+
+ default:
+ nv_error_msg("Unhandled GVO CSC event received: %d\n",
+ attribute);
+ break;
+ }
+
+} /* gvo_csc_event_recieved() */
+
+
+
/*
* build_opengl_only_msg() - build a message to inform the user that
* custom CSC will only be applied to OpenGL GVO output; this returns
diff --git a/src/gtk+-2.x/ctkgvo-csc.h b/src/gtk+-2.x/ctkgvo-csc.h
index ff50cfe..04757df 100644
--- a/src/gtk+-2.x/ctkgvo-csc.h
+++ b/src/gtk+-2.x/ctkgvo-csc.h
@@ -62,6 +62,7 @@ struct _CtkGvoCsc
NvCtrlAttributeHandle *handle;
CtkConfig *ctk_config;
+ CtkEvent *ctk_event;
CtkGvo *gvo_parent;
GtkWidget *banner_box;
diff --git a/src/gtk+-2.x/ctkgvo-sync.c b/src/gtk+-2.x/ctkgvo-sync.c
index cf3554f..1ac2e12 100644
--- a/src/gtk+-2.x/ctkgvo-sync.c
+++ b/src/gtk+-2.x/ctkgvo-sync.c
@@ -84,7 +84,6 @@ static void update_gvo_sync_sensitivity(CtkGvoSync *ctk_gvo_sync);
static void update_input_video_format_text_entry(CtkGvoSync *ctk_gvo_sync);
static void post_composite_termination_toggled(CtkGvoSync *ctk_gvo_sync,
gboolean enabled);
-static void update_delay_spin_buttons_range(CtkGvoSync *ctk_gvo_sync);
static void detect_input_toggled(GtkToggleButton *togglebutton,
@@ -335,7 +334,8 @@ GtkWidget* ctk_gvo_sync_new(NvCtrlAttributeHandle *handle,
GtkWidget *table, *menu;
- gint val, i, width, height;
+ gint val, i;
+ NVCTRLAttributeValidValuesRec valid;
ReturnStatus ret;
gint row;
@@ -531,9 +531,6 @@ GtkWidget* ctk_gvo_sync_new(NvCtrlAttributeHandle *handle,
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);
-
- ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_PIXELS, &val);
- if (ret != NvCtrlSuccess) val = 0;
ctk_gvo_sync->sync_lock_status_text = gtk_label_new("");
@@ -551,116 +548,114 @@ GtkWidget* ctk_gvo_sync_new(NvCtrlAttributeHandle *handle,
/*
- * Synchronization Delay/Advance
+ * Synchronization Skew (Delay/Advance)
*/
-
- ctk_gvo_get_video_format_resolution(ctk_gvo_sync->input_video_format,
- &width, &height);
/* NV_CTRL_GVO_SYNC_DELAY_PIXELS */
- if ( ctk_gvo_sync->caps && NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
- label = gtk_label_new("HSync Advance:");
- } else {
- label = gtk_label_new("HSync Delay:");
- }
+ ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_GVO_SYNC_DELAY_PIXELS,
+ &valid);
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
- GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);
-
- ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_PIXELS, &val);
- if (ret != NvCtrlSuccess) val = 0;
+ if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE)) {
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_PIXELS, &val);
+ if (ret != NvCtrlSuccess) val = 0;
- if (width < 1) width = 1;
+ if (ctk_gvo_sync->caps & NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW) {
+ label = gtk_label_new("HSync Advance:");
+ help_text = __hsync_advance_help;
+ } else {
+ label = gtk_label_new("HSync Delay:");
+ help_text = __hsync_delay_help;
+ }
- if ( ctk_gvo_sync->caps && NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
- width = INT_MAX;
- help_text = __hsync_advance_help;
- } else {
- help_text = __hsync_delay_help;
- }
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
+ GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);
- ctk_gvo_sync->hsync_delay_spin_button =
- gtk_spin_button_new_with_range(0.0, width, 1);
+ ctk_gvo_sync->hsync_delay_spin_button =
+ gtk_spin_button_new_with_range(valid.u.range.min,
+ valid.u.range.max, 1);
- ctk_config_set_tooltip(ctk_config,
- ctk_gvo_sync->hsync_delay_spin_button,
- help_text);
+ ctk_config_set_tooltip(ctk_config,
+ ctk_gvo_sync->hsync_delay_spin_button,
+ help_text);
- gtk_spin_button_set_value
- (GTK_SPIN_BUTTON(ctk_gvo_sync->hsync_delay_spin_button), val);
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON(ctk_gvo_sync->hsync_delay_spin_button), val);
- g_signal_connect(G_OBJECT(ctk_gvo_sync->hsync_delay_spin_button),
- "value-changed",
- G_CALLBACK(hsync_delay_changed), ctk_gvo_sync);
+ g_signal_connect(G_OBJECT(ctk_gvo_sync->hsync_delay_spin_button),
+ "value-changed",
+ G_CALLBACK(hsync_delay_changed), ctk_gvo_sync);
- hbox = gtk_hbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), ctk_gvo_sync->hsync_delay_spin_button,
- FALSE, FALSE, 0);
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_gvo_sync->hsync_delay_spin_button,
+ FALSE, FALSE, 0);
- label = gtk_label_new("(pixels)");
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), label,
- FALSE, FALSE, 0);
+ label = gtk_label_new("(pixels)");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), label,
+ FALSE, FALSE, 0);
- gtk_table_attach(GTK_TABLE(table), hbox,
- 1, 2, row, row+1,
- GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
- TABLE_PADDING, TABLE_PADDING);
- row++;
+ gtk_table_attach(GTK_TABLE(table), hbox,
+ 1, 2, row, row+1,
+ GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
+ TABLE_PADDING, TABLE_PADDING);
+ row++;
+ }
/* NV_CTRL_GVO_SYNC_DELAY_LINES */
- if ( ctk_gvo_sync->caps && NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
- label = gtk_label_new("VSync Advance:");
- } else {
- label = gtk_label_new("VSync Delay:");
- }
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
- GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);
+ ret = NvCtrlGetValidAttributeValues(handle, NV_CTRL_GVO_SYNC_DELAY_LINES,
+ &valid);
- ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_LINES, &val);
- if (ret != NvCtrlSuccess) val = 0;
-
- if (height < 1) height = 1;
+ if ((ret == NvCtrlSuccess) && (valid.type == ATTRIBUTE_TYPE_RANGE)) {
+ ret = NvCtrlGetAttribute(handle, NV_CTRL_GVO_SYNC_DELAY_LINES, &val);
+ if (ret != NvCtrlSuccess) val = 0;
- if ( ctk_gvo_sync->caps && NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
- height = INT_MAX;
- help_text = __vsync_advance_help;
- } else {
- help_text = __vsync_delay_help;
- }
+ if (ctk_gvo_sync->caps & NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW) {
+ label = gtk_label_new("VSync Advance:");
+ help_text = __vsync_advance_help;
+ } else {
+ label = gtk_label_new("VSync Delay:");
+ help_text = __vsync_delay_help;
+ }
- ctk_gvo_sync->vsync_delay_spin_button =
- gtk_spin_button_new_with_range(0.0, height, 1);
-
- ctk_config_set_tooltip(ctk_config,
- ctk_gvo_sync->vsync_delay_spin_button,
- help_text);
- gtk_spin_button_set_value
- (GTK_SPIN_BUTTON(ctk_gvo_sync->vsync_delay_spin_button), val);
-
- g_signal_connect(G_OBJECT(ctk_gvo_sync->vsync_delay_spin_button),
- "value-changed",
- G_CALLBACK(vsync_delay_changed), ctk_gvo_sync);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1,
+ GTK_FILL, GTK_FILL, TABLE_PADDING, TABLE_PADDING);
- hbox = gtk_hbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), ctk_gvo_sync->vsync_delay_spin_button,
- FALSE, FALSE, 0);
+ ctk_gvo_sync->vsync_delay_spin_button =
+ gtk_spin_button_new_with_range(valid.u.range.min,
+ valid.u.range.max, 1);
- label = gtk_label_new("(lines)");
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_box_pack_start(GTK_BOX(hbox), label,
- FALSE, FALSE, 0);
+ ctk_config_set_tooltip(ctk_config,
+ ctk_gvo_sync->vsync_delay_spin_button,
+ help_text);
- gtk_table_attach(GTK_TABLE(table), hbox,
- 1, 2, row, row+1,
- GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
- TABLE_PADDING, TABLE_PADDING);
- row++;
+ gtk_spin_button_set_value
+ (GTK_SPIN_BUTTON(ctk_gvo_sync->vsync_delay_spin_button), val);
+
+ g_signal_connect(G_OBJECT(ctk_gvo_sync->vsync_delay_spin_button),
+ "value-changed",
+ G_CALLBACK(vsync_delay_changed), ctk_gvo_sync);
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox),
+ ctk_gvo_sync->vsync_delay_spin_button,
+ FALSE, FALSE, 0);
+
+ label = gtk_label_new("(lines)");
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(hbox), label,
+ FALSE, FALSE, 0);
+
+ gtk_table_attach(GTK_TABLE(table), hbox,
+ 1, 2, row, row+1,
+ GTK_FILL /*| GTK_EXPAND*/, GTK_FILL,
+ TABLE_PADDING, TABLE_PADDING);
+ row++;
+ }
/* create the watch cursor (for use when the "Detect" button is toggled" */
@@ -716,7 +711,7 @@ static GtkWidget *start_menu(const gchar *name, GtkWidget *table,
static void finish_menu(GtkWidget *menu, GtkWidget *table, const gint row)
{
- ctk_drop_down_menu_finalize(CTK_DROP_DOWN_MENU(menu));
+ gtk_widget_show_all(menu);
gtk_table_attach(GTK_TABLE(table), menu, 1, 2, row, row+1,
GTK_FILL | GTK_EXPAND, GTK_FILL,
@@ -930,8 +925,14 @@ static void update_gvo_sync_sensitivity(CtkGvoSync *ctk_gvo_sync)
sensitive = (sensitive && sync_signal_detected(ctk_gvo_sync));
- gtk_widget_set_sensitive(ctk_gvo_sync->hsync_delay_spin_button, sensitive);
- gtk_widget_set_sensitive(ctk_gvo_sync->vsync_delay_spin_button, sensitive);
+ if (ctk_gvo_sync->hsync_delay_spin_button) {
+ gtk_widget_set_sensitive(ctk_gvo_sync->hsync_delay_spin_button,
+ sensitive);
+ }
+ if (ctk_gvo_sync->vsync_delay_spin_button) {
+ gtk_widget_set_sensitive(ctk_gvo_sync->vsync_delay_spin_button,
+ sensitive);
+ }
} /* update_gvo_sync_sensitivity() */
@@ -1040,32 +1041,6 @@ static void post_sync_format_menu_changed(CtkGvoSync *ctk_gvo_sync)
-/*
- * update_delay_spin_buttons_range() - Updates the range of the
- * delay spin buttons.
- */
-
-static void update_delay_spin_buttons_range(CtkGvoSync *ctk_gvo_sync)
-{
- gint w, h;
-
- if ( ctk_gvo_sync->caps && NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
- // No need to reset max values
- return;
- }
-
- ctk_gvo_get_video_format_resolution(ctk_gvo_sync->input_video_format,
- &w, &h);
-
- gtk_spin_button_set_range
- (GTK_SPIN_BUTTON(ctk_gvo_sync->hsync_delay_spin_button), 0, 2*w);
- gtk_spin_button_set_range
- (GTK_SPIN_BUTTON(ctk_gvo_sync->vsync_delay_spin_button), 0, 2*h);
-
-} /* update_delay_spin_buttons_range() */
-
-
-
/**** UI Event Handlers ************************************************/
@@ -1359,30 +1334,34 @@ static void gvo_sync_event_received(GtkObject *object,
case NV_CTRL_GVO_SYNC_DELAY_PIXELS:
widget = ctk_gvo_sync->hsync_delay_spin_button;
+
+ if (widget) {
+ g_signal_handlers_block_by_func(G_OBJECT(widget),
+ G_CALLBACK(hsync_delay_changed),
+ (gpointer) ctk_gvo_sync);
- g_signal_handlers_block_by_func(G_OBJECT(widget),
- G_CALLBACK(hsync_delay_changed),
- (gpointer) ctk_gvo_sync);
-
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), value);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), value);
- g_signal_handlers_unblock_by_func(G_OBJECT(widget),
- G_CALLBACK(hsync_delay_changed),
- (gpointer) ctk_gvo_sync);
+ g_signal_handlers_unblock_by_func(G_OBJECT(widget),
+ G_CALLBACK(hsync_delay_changed),
+ (gpointer) ctk_gvo_sync);
+ }
break;
case NV_CTRL_GVO_SYNC_DELAY_LINES:
widget = ctk_gvo_sync->vsync_delay_spin_button;
- g_signal_handlers_block_by_func(G_OBJECT(widget),
- G_CALLBACK(vsync_delay_changed),
- (gpointer) ctk_gvo_sync);
-
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), value);
+ if (widget) {
+ g_signal_handlers_block_by_func(G_OBJECT(widget),
+ G_CALLBACK(vsync_delay_changed),
+ (gpointer) ctk_gvo_sync);
- g_signal_handlers_unblock_by_func(G_OBJECT(widget),
- G_CALLBACK(vsync_delay_changed),
- (gpointer) ctk_gvo_sync);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), value);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(widget),
+ G_CALLBACK(vsync_delay_changed),
+ (gpointer) ctk_gvo_sync);
+ }
break;
case NV_CTRL_GVO_COMPOSITE_TERMINATION:
@@ -1458,8 +1437,6 @@ static gint gvo_sync_probe_callback(gpointer data)
update_sync_lock_status_text(ctk_gvo_sync);
- update_delay_spin_buttons_range(ctk_gvo_sync);
-
update_gvo_sync_sensitivity(ctk_gvo_sync);
return TRUE;
@@ -1539,7 +1516,7 @@ GtkTextBuffer* ctk_gvo_sync_create_help(GtkTextTagTable *table,
ctk_help_heading(b, &i, "Sync Status");
ctk_help_para(b, &i, __sync_status_help);
- if ( ctk_gvo_sync->caps && NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
+ if ( ctk_gvo_sync->caps & NV_CTRL_GVO_CAPABILITIES_ADVANCE_SYNC_SKEW ) {
ctk_help_heading(b, &i, "HSync Advance");
ctk_help_para(b, &i, __hsync_advance_help);
ctk_help_heading(b, &i, "VSync Advance");
diff --git a/src/gtk+-2.x/ctkgvo.c b/src/gtk+-2.x/ctkgvo.c
index 28ad0c1..64910e3 100644
--- a/src/gtk+-2.x/ctkgvo.c
+++ b/src/gtk+-2.x/ctkgvo.c
@@ -106,13 +106,12 @@ static void finish_menu(GtkWidget *menu, GtkWidget *table, const gint row);
static void fill_output_video_format_menu(CtkGvo *ctk_gvo);
-static void trim_output_video_format_menu(CtkGvo *ctk_gvo);
static void output_video_format_ui_changed(CtkDropDownMenu *menu,
gpointer user_data);
static void post_output_video_format_changed(CtkGvo *ctk_gvo);
-static void validate_output_data_format(CtkGvo *ctk_gvo);
+static void fill_output_data_format_menu(CtkGvo *ctk_gvo);
static void output_data_format_ui_changed(CtkDropDownMenu *menu,
gpointer user_data);
static void post_output_data_format_changed(CtkGvo *ctk_gvo);
@@ -232,9 +231,39 @@ static GvoFormatDetails videoFormatDetails[] = {
static const GvoFormatName dataFormatNames[] = {
- { NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB444, "RGB -> YCrCb (4:4:4)" },
- { NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB422, "RGB -> YCrCb (4:2:2)" },
- { NV_CTRL_GVO_DATA_FORMAT_X8X8X8_444_PASSTHRU,"RGB (4:4:4)" },
+
+ /* Valid for Clone Mode */
+ { NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB444, "RGB -> YCrCb (4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R8G8B8_TO_YCRCB422, "RGB -> YCrCb (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X8X8X8_444_PASSTHRU, "RGB (4:4:4)" },
+
+ /* Invalid for Clone Mode usage */
+ { NV_CTRL_GVO_DATA_FORMAT_R8G8B8A8_TO_YCRCBA4444, "RGBA -> YCrCbA (4:4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R8G8B8Z10_TO_YCRCBZ4444, "RGBZ -> YCrCbZ (4:4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R8G8B8A8_TO_YCRCBA4224, "RGBA -> YCrCbA (4:2:2:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R8G8B8Z10_TO_YCRCBZ4224, "RGBZ -> YCrCbZ (4:2:2:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X8X8X8A8_4444_PASSTHRU, "RGBA (4:4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X8X8X8Z8_4444_PASSTHRU, "RGBZ (4:4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X10X10_444_PASSTHRU, "RGBA (4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X8X8_444_PASSTHRU, "RGB (4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X8X8A10_4444_PASSTHRU, "RGBA (4:4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X8X8Z10_4444_PASSTHRU, "RGBZ (4:4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_DUAL_R8G8B8_TO_DUAL_YCRCB422, "Dual RGB -> Dual YCrCb (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_DUAL_X8X8X8_TO_DUAL_422_PASSTHRU, "Dual RGB (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB422, "RGB -> YCrCb (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R10G10B10_TO_YCRCB444, "RGB -> YCrCb (4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X12X12X12_444_PASSTHRU, "RGB (4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R12G12B12_TO_YCRCB444, "RGB -> YCrCb (4:4:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X8X8X8_422_PASSTHRU, "RGB (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X8X8X8A8_4224_PASSTHRU, "RGB (4:2:2:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X8X8X8Z8_4224_PASSTHRU, "RGB (4:2:2:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X10X10_422_PASSTHRU, "RGB (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X8X8_422_PASSTHRU, "RGB (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X8X8A10_4224_PASSTHRU, "RGBA (4:2:2:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X10X8X8Z10_4224_PASSTHRU, "RGBZ (4:2:2:4)" },
+ { NV_CTRL_GVO_DATA_FORMAT_X12X12X12_422_PASSTHRU, "RGB (4:2:2)" },
+ { NV_CTRL_GVO_DATA_FORMAT_R12G12B12_TO_YCRCB422, "RGB -> YCrCb (4:2:2)" },
+
{ -1, NULL },
};
@@ -244,36 +273,6 @@ static const GvoFormatName dataFormatNames[] = {
/*
- * get_first_available_output_video_format() - returns the first available
- * output video format from the dropdown menu. This is needed since when
- * Frame Lock/Genlock are enabled, the default case of 487i may not be
- * appropriate.
- */
-
-static gint get_first_available_output_video_format(CtkGvo *ctk_gvo)
-{
- CtkDropDownMenu *dmenu =
- CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu);
- int i;
-
- /* look through the output video format dropdown for the first
- * available selection.
- */
- for (i = 0; i < dmenu->num_entries; i++) {
- if (GTK_WIDGET_IS_SENSITIVE(dmenu->values[i].menu_item)) {
- return dmenu->values[i].value;
- }
- }
-
- /* There are no available video formats? Fallback to 487i. */
-
- return NV_CTRL_GVO_VIDEO_FORMAT_487I_59_94_SMPTE259_NTSC;
-
-} /* get_first_available_output_video_format() */
-
-
-
-/*
* ctk_gvo_get_video_format_name() - return the name of the given video format
*/
@@ -294,26 +293,6 @@ const char *ctk_gvo_get_video_format_name(const gint format)
/*
- * ctk_gvo_get_data_format_name() - return the name of the given data format
- */
-
-const char *ctk_gvo_get_data_format_name(const gint format)
-{
- gint i;
-
- for (i = 0; dataFormatNames[i].name; i++) {
- if (dataFormatNames[i].format == format) {
- return dataFormatNames[i].name;
- }
- }
-
- return "Unknown";
-
-} /* ctk_gvo_get_data_format_name() */
-
-
-
-/*
* ctk_gvo_get_video_format_resolution() - return the width and height of the
* given video format
*/
@@ -336,299 +315,179 @@ void ctk_gvo_get_video_format_resolution(const gint format, gint *w, gint *h)
/*
- * ctk_gvo_get_type() - Returns the CtkGvo "class" type
+ * ctk_gvo_get_video_format_refresh() - return the refresh rate of the
+ * given video format
*/
-GType ctk_gvo_get_type(void)
+void ctk_gvo_get_video_format_refresh(const gint format, gint *r)
{
- static GType ctk_gvo_type = 0;
-
- if (!ctk_gvo_type) {
- static const GTypeInfo ctk_gvo_info = {
- sizeof (CtkGvoClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- NULL, /* constructor */
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (CtkGvo),
- 0, /* n_preallocs */
- NULL, /* instance_init */
- };
+ gint i;
+
+ *r = 0;
- ctk_gvo_type =
- g_type_register_static(GTK_TYPE_VBOX, "CtkGvo",
- &ctk_gvo_info, 0);
+ for (i = 0; videoFormatDetails[i].format != -1; i++) {
+ if (videoFormatDetails[i].format == format) {
+ *r = videoFormatDetails[i].rate;
+ return;
+ }
}
-
- return ctk_gvo_type;
-
-} /* ctk_gvo_get_type() */
+} /* ctk_gvo_get_video_format_refresh() */
/*
- * trim_output_video_format_menu() - given the current
- * OUTPUT_VIDEO_FORMAT and SYNC_MODE, set the sensitivity of each menu
- * entry and possibly update which of the output video mode dropdown
- * entries is currently selected.
+ * ctk_gvo_video_format_valid() - returns a bitmask indicating whether or not
+ * the currently selected video format is valid for clone mode based on the
+ * current X screen resolution and current sync method. Returns a bitmask
+ * indicating possible valid/invalid state of the mode.
*/
-static void trim_output_video_format_menu(CtkGvo *ctk_gvo)
-{
- ReturnStatus ret;
- NVCTRLAttributeValidValuesRec valid;
- gint bitmask, bitmask2, i, refresh_rate;
- gboolean sensitive, current_available;
+#define GVO_VIDEO_FORMAT_INVALID 0x00000000
+#define GVO_VIDEO_FORMAT_MODE_VALID 0x00000001
+#define GVO_VIDEO_FORMAT_RESOLUTION_VALID 0x00000002
+#define GVO_VIDEO_FORMAT_REFRESH_VALID 0x00000004
- /* retrieve the currently available values */
+#define GVO_VIDEO_FORMAT_VALID \
+ (GVO_VIDEO_FORMAT_MODE_VALID | \
+ GVO_VIDEO_FORMAT_RESOLUTION_VALID | \
+ GVO_VIDEO_FORMAT_REFRESH_VALID)
- ret = NvCtrlGetValidAttributeValues(ctk_gvo->handle,
- NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT,
- &valid);
+guint ctk_gvo_video_format_valid(CtkGvo *ctk_gvo, const gint format)
+{
+ gint width, height, refresh_rate, input_refresh_rate;
+ guint valid = GVO_VIDEO_FORMAT_VALID;
- /* if we failed to get the available values; assume none are valid */
- if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
- bitmask = 0;
- } else {
- bitmask = valid.u.bits.ints;
- }
-
- /* retrieve additional available values */
+ /* Keep track of whether we'll need to re-set the video format
+ * when enabling clone mode.
+ */
- ret = NvCtrlGetValidAttributeValues(ctk_gvo->handle,
- NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2,
- &valid);
+ /* Check to make sure the format size <= current screen size */
+ ctk_gvo_get_video_format_resolution(format, &width, &height);
- /* if we failed to get the available values; assume none are valid */
-
- if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
- bitmask2 = 0;
- } else {
- bitmask2 = valid.u.bits.ints;
+ /* Make sure the resolution fits */
+ if ((width > ctk_gvo->screen_width) || (height > ctk_gvo->screen_height)) {
+ valid &= ~(GVO_VIDEO_FORMAT_RESOLUTION_VALID);
}
-
- /*
- * if the SyncMode is genlock or framelock, trim the bitmask
- * accordingly: if GENLOCK, then the only bit allowed is the bit
- * that corresponds to the exact input mode; if FRAMELOCK, then
- * only modes with the same refresh rate as the input mode are
- * allowed.
- */
- if ((ctk_gvo->sync_mode == NV_CTRL_GVO_SYNC_MODE_GENLOCK) &&
- (ctk_gvo->input_video_format != NV_CTRL_GVO_VIDEO_FORMAT_NONE)) {
+ /* Check that format is supported */
+ if (((format < 32) &&
+ !((1 << format) & ctk_gvo->valid_output_video_format_mask[0])) ||
+ ((format >= 32) &&
+ !((1 << (format -32)) & ctk_gvo->valid_output_video_format_mask[1]))) {
+ valid &= ~(GVO_VIDEO_FORMAT_MODE_VALID);
+ }
- if (ctk_gvo->input_video_format < 32) {
- bitmask &= (1 << ctk_gvo->input_video_format);
- bitmask2 = 0;
- } else {
- bitmask = 0;
- bitmask2 &= (1 << (ctk_gvo->input_video_format - 32));
- }
+ /* Check that formats match if Genlock is enabled */
+ else if ((ctk_gvo->sync_mode == NV_CTRL_GVO_SYNC_MODE_GENLOCK) &&
+ (ctk_gvo->input_video_format != NV_CTRL_GVO_VIDEO_FORMAT_NONE) &&
+ (ctk_gvo->input_video_format != format)) {
+ valid &= ~(GVO_VIDEO_FORMAT_REFRESH_VALID);
}
-
- if ((ctk_gvo->sync_mode == NV_CTRL_GVO_SYNC_MODE_FRAMELOCK) &&
- (ctk_gvo->input_video_format != NV_CTRL_GVO_VIDEO_FORMAT_NONE)) {
- refresh_rate = 0;
+
+ /* Check that format refresh rates match if Frame Lock is enabled */
+ else if ((ctk_gvo->sync_mode == NV_CTRL_GVO_SYNC_MODE_FRAMELOCK) &&
+ (ctk_gvo->input_video_format != NV_CTRL_GVO_VIDEO_FORMAT_NONE)) {
+
+ /* Get the refresh rate */
+ ctk_gvo_get_video_format_refresh(format, &refresh_rate);
/* Get the current input refresh rate */
- for (i = 0; videoFormatDetails[i].format != -1; i++) {
- if (videoFormatDetails[i].format == ctk_gvo->input_video_format) {
- refresh_rate = videoFormatDetails[i].rate;
- break;
- }
- }
+ ctk_gvo_get_video_format_refresh(ctk_gvo->input_video_format,
+ &input_refresh_rate);
- /* Mask out refresh rates that don't match */
- for (i = 0; videoFormatDetails[i].format != -1; i++) {
- gboolean match = FALSE;
-
- if (videoFormatDetails[i].rate == refresh_rate) {
- match = TRUE;
-
- } else if (ctk_gvo->caps &
- NV_CTRL_GVO_CAPABILITIES_MULTIRATE_SYNC) {
-
- /* Some GVO devices support multi-rate synchronization.
- * For these devices, we just need to check that the
- * fractional part of the rate are either both zero or
- * both non-zero.
- */
- if (((videoFormatDetails[i].rate % 1000) ? TRUE : FALSE) ==
- ((refresh_rate % 1000) ? TRUE : FALSE)) {
- match = TRUE;
- }
- } else {
- match = FALSE;
- }
+ /* Check that the refresh rates are the same, or, for those
+ * GVO devices that support multi-rate synchronization, check
+ * that the fractional part of the rates are either both zero
+ * or both non-zero.
+ */
- if (!match) {
- if (videoFormatDetails[i].format < 32) {
- bitmask &= ~(1 << videoFormatDetails[i].format);
- } else {
- bitmask2 &= ~(1 << (videoFormatDetails[i].format - 32));
- }
- }
+ if ((refresh_rate != input_refresh_rate) &&
+ (!(ctk_gvo->caps & NV_CTRL_GVO_CAPABILITIES_MULTIRATE_SYNC) ||
+ (((refresh_rate % 1000) ? TRUE : FALSE) !=
+ ((input_refresh_rate % 1000) ? TRUE : FALSE)))) {
+ valid &= ~(GVO_VIDEO_FORMAT_REFRESH_VALID);
}
}
- /*
- * loop over each video format; if that format is set in the
- * bitmask, then it is available
- */
+ return valid;
- current_available = FALSE;
- for (i = 0; videoFormatNames[i].name; i++) {
- if (((videoFormatNames[i].format < 32) &&
- ((1 << videoFormatNames[i].format) & bitmask)) ||
- ((videoFormatNames[i].format >= 32) &&
- (((1 << (videoFormatNames[i].format - 32)) & bitmask2)))) {
- sensitive = TRUE;
- } else {
- sensitive = FALSE;
- }
+} /* ctk_gvo_video_format_valid() */
- ctk_drop_down_menu_set_value_sensitive
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu),
- videoFormatNames[i].format, sensitive);
- /* if the current video is not sensitive, take note */
-
- if ((ctk_gvo->output_video_format == videoFormatNames[i].format) &&
- sensitive) {
- current_available = TRUE;
- }
- }
-
- /*
- * if the current video is not available, then make the first
- * available format current
- */
-
- if (!current_available && bitmask) {
-
- for (i = 0; videoFormatNames[i].name; i++) {
- if (((videoFormatNames[i].format < 32) &&
- ((1 << videoFormatNames[i].format) & bitmask)) ||
- ((videoFormatNames[i].format >= 32) &&
- ((1 << (videoFormatNames[i].format - 32)) & bitmask2))) {
-
- /* Invalidate the format so it gets set when clone mode is
- * enabled.
- */
- ctk_gvo->output_video_format_valid = FALSE;
-
- g_signal_handlers_block_by_func
- (G_OBJECT(ctk_gvo->output_video_format_menu),
- G_CALLBACK(output_video_format_ui_changed),
- (gpointer) ctk_gvo);
- ctk_drop_down_menu_set_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu),
- videoFormatNames[i].format);
+/*
+ * ctk_gvo_get_data_format_name() - return the name of the given data format
+ */
- g_signal_handlers_unblock_by_func
- (G_OBJECT(ctk_gvo->output_video_format_menu),
- G_CALLBACK(output_video_format_ui_changed),
- (gpointer) ctk_gvo);
- break;
- }
+const char *ctk_gvo_get_data_format_name(const gint format)
+{
+ gint i;
+
+ for (i = 0; dataFormatNames[i].name; i++) {
+ if (dataFormatNames[i].format == format) {
+ return dataFormatNames[i].name;
}
}
- /*
- * cache the bitmask
- */
+ return "Unknown";
- ctk_gvo->valid_output_video_format_mask[0] = bitmask;
- ctk_gvo->valid_output_video_format_mask[1] = bitmask2;
-
-} /* trim_output_video_format_menu() */
+} /* ctk_gvo_get_data_format_name() */
/*
- * validate_output_video_format() - Keep tabs on the output
- * video format. If some other client sets the output video format to
- * something clone mode can't do, we'll just need to make sure that
- * we re-set the output video format when the user selects to enable
- * clone mode.
- *
- * NOTE: The gtk signal handler for the video format menu should not
- * be enabled while calling this function.
+ * ctk_gvo_data_format_valid() - return whether or not the given data
+ * format is valid for clone mode.
*/
-static void validate_output_video_format(CtkGvo *ctk_gvo)
+gboolean ctk_gvo_data_format_valid(const gint format)
{
- gint bitmask, bitmask2;
- gint width, height;
- gint format = ctk_gvo->output_video_format;
-
- /* Keep track of whether we'll need to re-set the video format
- * when enabling clone mode.
- */
-
- /* Check to make sure the format size <= current screen size */
- ctk_gvo_get_video_format_resolution(format, &width, &height);
-
- /* Don't expose modes bigger than the current X Screen size */
- if ((width > ctk_gvo->screen_width) ||
- (height > ctk_gvo->screen_height)) {
- /* Format is invalid due to screen size limitations */
- ctk_gvo->output_video_format_valid = FALSE;
- return;
- }
-
- /* Check to make sure genlock/framelock requirements are ment */
- bitmask = ctk_gvo->valid_output_video_format_mask[0];
- bitmask2 = ctk_gvo->valid_output_video_format_mask[1];
-
- if (((format < 32) && !((1 << format) & bitmask)) ||
- ((format >= 32) && !((1 << (format - 32)) & bitmask2))) {
- /* Format is invalid due to genlock/framelock requirements */
- ctk_gvo->output_video_format_valid = FALSE;
- return;
+ gint i;
+
+ for (i = 0; dataFormatNames[i].name; i++) {
+ if (dataFormatNames[i].format == format) {
+ /* Only the first three formats are valid */
+ return (i < 3) ? TRUE : FALSE;
+ }
}
- /* If we got this far, then the format is valid. */
- ctk_gvo->output_video_format_valid = TRUE;
+ return FALSE;
-} /* validate_output_video_format() */
+} /* ctk_gvo_data_format_valid() */
/*
- * validate_output_data_format() - Keep tabs on the output
- * data format. If some other client sets the output data format to
- * something clone mode can't do, we'll just need to make sure that
- * we re-set the output data format when the user selects to enable
- * clone mode.
- *
- * NOTE: The gtk signal handler for the data format menu should not
- * be enabled while calling this function.
+ * ctk_gvo_get_type() - Returns the CtkGvo "class" type
*/
-static void validate_output_data_format(CtkGvo *ctk_gvo)
+GType ctk_gvo_get_type(void)
{
- int i;
-
- /* Keep track of whether we'll need to re-set the data format
- * when enabling clone mode.
- */
- for (i = 0; dataFormatNames[i].name; i++) {
- if (ctk_gvo->output_data_format == dataFormatNames[i].format) {
- /* Value is OK */
- ctk_gvo->output_data_format_valid = TRUE;
- return;
- }
- }
+ static GType ctk_gvo_type = 0;
- ctk_gvo->output_data_format_valid = FALSE;
+ if (!ctk_gvo_type) {
+ static const GTypeInfo ctk_gvo_info = {
+ sizeof (CtkGvoClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* constructor */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (CtkGvo),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
-} /* validate_output_data_format() */
+ ctk_gvo_type =
+ g_type_register_static(GTK_TYPE_VBOX, "CtkGvo",
+ &ctk_gvo_info, 0);
+ }
+
+ return ctk_gvo_type;
+
+} /* ctk_gvo_get_type() */
@@ -647,7 +506,7 @@ GtkWidget* ctk_gvo_new(NvCtrlAttributeHandle *handle,
GtkWidget *hbox, *vbox, *alignment, *label;
ReturnStatus ret;
gchar scratch[64], *firmware, *string;
- gint val, i, width, height;
+ gint val, width, height;
GtkWidget *frame, *table, *menu;
@@ -776,18 +635,10 @@ GtkWidget* ctk_gvo_new(NvCtrlAttributeHandle *handle,
fill_output_video_format_menu(ctk_gvo);
finish_menu(menu, table, 0);
-
- /* Make sure that the video format selected is valid for clone mode */
-
- validate_output_video_format(ctk_gvo);
- if (ctk_gvo->output_video_format_valid) {
- val = ctk_gvo->output_video_format;
- } else {
- val = get_first_available_output_video_format(ctk_gvo);
- }
ctk_drop_down_menu_set_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu), val);
+ (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu),
+ ctk_gvo->output_video_format);
g_signal_connect(G_OBJECT(ctk_gvo->output_video_format_menu),
"changed", G_CALLBACK(output_video_format_ui_changed),
@@ -799,26 +650,14 @@ GtkWidget* ctk_gvo_new(NvCtrlAttributeHandle *handle,
ctk_gvo->output_data_format_menu = menu;
ctk_config_set_tooltip(ctk_config, CTK_DROP_DOWN_MENU(menu)->option_menu,
__clone_mode_data_format_help);
-
- for (i = 0; dataFormatNames[i].name; i++) {
- ctk_drop_down_menu_append_item(CTK_DROP_DOWN_MENU(menu),
- dataFormatNames[i].name,
- dataFormatNames[i].format);
- }
+
+ fill_output_data_format_menu(ctk_gvo);
finish_menu(menu, table, 1);
- /* Make sure that the data format selected is valid for clone mode */
-
- validate_output_data_format(ctk_gvo);
- if (ctk_gvo->output_data_format_valid) {
- val = ctk_gvo->output_data_format;
- } else {
- val = DEFAULT_OUTPUT_DATA_FORMAT;
- }
-
ctk_drop_down_menu_set_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_data_format_menu), val);
+ (CTK_DROP_DOWN_MENU(ctk_gvo->output_data_format_menu),
+ ctk_gvo->output_data_format);
g_signal_connect(G_OBJECT(ctk_gvo->output_data_format_menu),
"changed", G_CALLBACK(output_data_format_ui_changed),
@@ -1075,7 +914,7 @@ static GtkWidget *start_menu(const gchar *name, GtkWidget *table,
static void finish_menu(GtkWidget *menu, GtkWidget *table, const gint row)
{
- ctk_drop_down_menu_finalize(CTK_DROP_DOWN_MENU(menu));
+ gtk_widget_show_all(menu);
gtk_table_attach(GTK_TABLE(table), menu, 1, 2, row, row+1,
GTK_FILL | GTK_EXPAND, GTK_FILL,
@@ -1092,10 +931,17 @@ static void finish_menu(GtkWidget *menu, GtkWidget *table, const gint row)
static void fill_output_video_format_menu(CtkGvo *ctk_gvo)
{
int i;
- int width, height;
CtkDropDownMenu *dmenu =
CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu);
+ GtkWidget *label;
+ guint valid;
+ gint num_valid_entries = 0;
+ gchar *str;
+ gchar *tmp;
+
+ ctk_drop_down_menu_reset(CTK_DROP_DOWN_MENU(dmenu));
+
for (i = 0; videoFormatNames[i].name; i++) {
/*
@@ -1108,44 +954,187 @@ static void fill_output_video_format_menu(CtkGvo *ctk_gvo)
return;
}
- /* check that the current X screen can support the width and height */
-
- width = videoFormatDetails[i].width;
- height = videoFormatDetails[i].height;
+ valid = ctk_gvo_video_format_valid(ctk_gvo,
+ videoFormatNames[i].format);
- /* Don't expose modes bigger than the current X Screen size */
- if ((width > ctk_gvo->screen_width) ||
- (height > ctk_gvo->screen_height)) {
+ /* Mode must be supported */
+ if (!(valid & GVO_VIDEO_FORMAT_MODE_VALID)) {
continue;
}
- ctk_drop_down_menu_append_item(dmenu,
- videoFormatNames[i].name,
- videoFormatNames[i].format);
+ /* Resolution must fit (or this is the selected mode) */
+ if (!(valid & GVO_VIDEO_FORMAT_RESOLUTION_VALID) &&
+ (ctk_gvo->output_video_format != videoFormatNames[i].format)) {
+ continue;
+ }
+
+ if (valid == GVO_VIDEO_FORMAT_VALID) {
+ str = (gchar *)videoFormatNames[i].name;
+ } else {
+ str = g_strconcat(videoFormatNames[i].name, " -", NULL);
+
+ if (!(valid & GVO_VIDEO_FORMAT_RESOLUTION_VALID)) {
+ tmp = g_strconcat(str, " Resolution mismatch", NULL);
+ g_free(str);
+ str = tmp;
+ }
+ if (!(valid & GVO_VIDEO_FORMAT_REFRESH_VALID)) {
+ if (!(valid & GVO_VIDEO_FORMAT_RESOLUTION_VALID)) {
+ tmp = g_strconcat(str, ",", NULL);
+ g_free(str);
+ str = tmp;
+ }
+ tmp = g_strconcat(str, " Refresh mismatch", NULL);
+ g_free(str);
+ str = tmp;
+ }
+ }
+
+ label = ctk_drop_down_menu_append_item(dmenu, str,
+ videoFormatNames[i].format);
+ if (str != videoFormatNames[i].name) {
+ g_free(str);
+ }
+
+ /* Gray out entry if it is not valid */
+ gtk_widget_set_sensitive(label, (valid == GVO_VIDEO_FORMAT_VALID));
+
+ if (valid == GVO_VIDEO_FORMAT_VALID) {
+ num_valid_entries++;
+ }
}
- ctk_gvo->has_output_video_formats =
- ((dmenu->num_entries > 0) ? TRUE : FALSE);
-
- if (!ctk_gvo->has_output_video_formats) {
- nv_warning_msg("No GVO video formats will fit the current X screen of "
- "%d x %d; please create an X screen of atleast "
- "720 x 487; not exposing GVO page.\n",
+ /* Show special menu if there are no valid entries */
+ if (num_valid_entries <= 0) {
+ nv_warning_msg("There are currently no GVO video formats valid for "
+ "use with Clone Mode. Please make sure that the X "
+ "screen resolution (currently %d x %d) is at least "
+ "720 x 487.\n",
ctk_gvo->screen_width, ctk_gvo->screen_height);
- ctk_drop_down_menu_append_item
- (dmenu,
- "*** X Screen is smaller than 720x487 ***",
- 0);
+ ctk_drop_down_menu_reset(CTK_DROP_DOWN_MENU(dmenu));
+ label = ctk_drop_down_menu_append_item(dmenu,
+ "*** X screen is smaller than "
+ "720x487 ***",
+ ctk_gvo->output_video_format);
+ gtk_widget_set_sensitive(label, FALSE);
}
- /* Trim output video format based on sync mode */
- trim_output_video_format_menu(ctk_gvo);
-
} /* fill_output_video_format_menu() */
+/*
+ * rebuild_output_video_format_menu() - Reconsutrcts the output data format
+ * menu.
+ */
+
+static void rebuild_output_video_format_menu(CtkGvo *ctk_gvo)
+{
+ CtkDropDownMenu *dmenu =
+ CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(dmenu),
+ G_CALLBACK(output_video_format_ui_changed),
+ (gpointer) ctk_gvo);
+
+ fill_output_video_format_menu(ctk_gvo);
+
+ ctk_drop_down_menu_set_current_value
+ (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu),
+ ctk_gvo->output_video_format);
+
+ gtk_widget_show_all(GTK_WIDGET(dmenu));
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(dmenu),
+ G_CALLBACK(output_video_format_ui_changed),
+ (gpointer) ctk_gvo);
+
+ update_gvo_sensitivity(ctk_gvo);
+
+} /* rebuild_output_video_format_menu() */
+
+
+
+/*
+ * fill_output_data_format_menu() - Populates the output data format menu.
+ */
+
+static void fill_output_data_format_menu(CtkGvo *ctk_gvo)
+{
+ int i;
+ CtkDropDownMenu *dmenu =
+ CTK_DROP_DOWN_MENU(ctk_gvo->output_data_format_menu);
+ GtkWidget *label;
+ gboolean valid;
+ gchar *str;
+
+ ctk_drop_down_menu_reset(CTK_DROP_DOWN_MENU(dmenu));
+
+ for (i = 0; dataFormatNames[i].name; i++) {
+ valid = ctk_gvo_data_format_valid(dataFormatNames[i].format);
+ if (!valid &&
+ (ctk_gvo->output_data_format != dataFormatNames[i].format)) {
+ continue;
+ }
+
+ if (valid) {
+ str = (gchar *)dataFormatNames[i].name;
+ } else {
+ str = g_strconcat(dataFormatNames[i].name,
+ " - Invalid for Clone Mode", NULL);
+ }
+
+ label = ctk_drop_down_menu_append_item(dmenu, str,
+ dataFormatNames[i].format);
+ if (str != dataFormatNames[i].name) {
+ g_free(str);
+ }
+
+ gtk_widget_set_sensitive(label, (valid ? TRUE : FALSE));
+ }
+
+} /* fill_output_data_format_menu() */
+
+
+
+/*
+ * rebuild_output_data_format_menu() - Reconsutrcts the output data format
+ * menu.
+ */
+
+static void rebuild_output_data_format_menu(CtkGvo *ctk_gvo)
+{
+ CtkDropDownMenu *dmenu =
+ CTK_DROP_DOWN_MENU(ctk_gvo->output_data_format_menu);
+
+ g_signal_handlers_block_by_func
+ (G_OBJECT(dmenu),
+ G_CALLBACK(output_data_format_ui_changed),
+ (gpointer) ctk_gvo);
+
+ fill_output_data_format_menu(ctk_gvo);
+
+ ctk_drop_down_menu_set_current_value
+ (CTK_DROP_DOWN_MENU(ctk_gvo->output_data_format_menu),
+ ctk_gvo->output_data_format);
+
+ gtk_widget_show_all(GTK_WIDGET(dmenu));
+
+ g_signal_handlers_unblock_by_func
+ (G_OBJECT(dmenu),
+ G_CALLBACK(output_data_format_ui_changed),
+ (gpointer) ctk_gvo);
+
+ update_gvo_sensitivity(ctk_gvo);
+
+} /* rebuild_output_data_format_menu() */
+
+
+
+
/**** Initialization Functions ***********************************************/
/*
@@ -1157,6 +1146,7 @@ static gboolean query_init_gvo_state(CtkGvo *ctk_gvo)
{
gint val;
ReturnStatus ret;
+ NVCTRLAttributeValidValuesRec valid;
/* Check if this screen supports GVO */
@@ -1202,6 +1192,27 @@ static gboolean query_init_gvo_state(CtkGvo *ctk_gvo)
val = DEFAULT_OUTPUT_VIDEO_FORMAT;
}
ctk_gvo->output_video_format = val;
+
+ /* Valid output video formats */
+
+ ret = NvCtrlGetValidAttributeValues(ctk_gvo->handle,
+ NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT,
+ &valid);
+ if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
+ ctk_gvo->valid_output_video_format_mask[0] = 0;
+ } else {
+ ctk_gvo->valid_output_video_format_mask[0] = valid.u.bits.ints;
+ }
+
+ ret = NvCtrlGetValidAttributeValues(ctk_gvo->handle,
+ NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2,
+ &valid);
+
+ if ((ret != NvCtrlSuccess) || (valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
+ ctk_gvo->valid_output_video_format_mask[1] = 0;
+ } else {
+ ctk_gvo->valid_output_video_format_mask[1] = valid.u.bits.ints;
+ }
/* Output data format */
@@ -1323,14 +1334,31 @@ static void output_video_format_ui_changed(CtkDropDownMenu *menu,
gpointer user_data)
{
CtkGvo *ctk_gvo = CTK_GVO(user_data);
+ guint was_valid;
+
+ was_valid = ctk_gvo_video_format_valid(ctk_gvo,
+ ctk_gvo->output_video_format);
ctk_gvo->output_video_format = ctk_drop_down_menu_get_current_value(menu);
- ctk_gvo->output_video_format_valid = TRUE;
+
+ if (ctk_gvo_video_format_valid(ctk_gvo, ctk_gvo->output_video_format) !=
+ GVO_VIDEO_FORMAT_VALID) {
+ /* Video format is invalid, don't set it */
+ update_gvo_sensitivity(ctk_gvo);
+ return;
+ }
NvCtrlSetAttribute(ctk_gvo->handle,
NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT,
ctk_gvo->output_video_format);
+ /* Rebuild menu to remove previously invalid entry */
+ if (was_valid != GVO_VIDEO_FORMAT_VALID) {
+ rebuild_output_video_format_menu(ctk_gvo);
+ }
+
+ update_gvo_sensitivity(ctk_gvo);
+
post_output_video_format_changed(ctk_gvo);
} /* output_video_format_ui_changed() */
@@ -1346,13 +1374,29 @@ static void output_data_format_ui_changed(CtkDropDownMenu *menu,
gpointer user_data)
{
CtkGvo *ctk_gvo = CTK_GVO(user_data);
-
+ gboolean was_valid;
+
+
+ was_valid = ctk_gvo_data_format_valid(ctk_gvo->output_data_format);
+
ctk_gvo->output_data_format = ctk_drop_down_menu_get_current_value(menu);
- ctk_gvo->output_data_format_valid = TRUE;
+
+ if (!ctk_gvo_data_format_valid(ctk_gvo->output_data_format)) {
+ /* Data format is invalid, don't set it */
+ update_gvo_sensitivity(ctk_gvo);
+ return;
+ }
NvCtrlSetAttribute(ctk_gvo->handle, NV_CTRL_GVO_DATA_FORMAT,
ctk_gvo->output_data_format);
-
+
+ /* Rebuild menu to remove previously invalid entry */
+ if (!was_valid) {
+ rebuild_output_data_format_menu(ctk_gvo);
+ }
+
+ update_gvo_sensitivity(ctk_gvo);
+
post_output_data_format_changed(ctk_gvo);
} /* output_data_format_ui_changed() */
@@ -1408,39 +1452,11 @@ static void clone_mode_button_ui_toggled(GtkWidget *button, gpointer user_data)
gint val;
enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
-
-
- /*
- * When enabling clone mode, we must make sure that the output
- * video format and output data format are something clone mode
- * can support.
- */
-
- if (enabled) {
- if (!ctk_gvo->output_video_format_valid) {
- val = ctk_drop_down_menu_get_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu));
- ctk_gvo->output_video_format = val;
- ctk_gvo->output_video_format_valid = TRUE;
- NvCtrlSetAttribute(ctk_gvo->handle,
- NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT,
- ctk_gvo->output_video_format);
- }
- if (!ctk_gvo->output_data_format_valid) {
- val = ctk_drop_down_menu_get_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_data_format_menu));
- ctk_gvo->output_data_format = val;
- ctk_gvo->output_data_format_valid = TRUE;
- NvCtrlSetAttribute(ctk_gvo->handle,
- NV_CTRL_GVO_DATA_FORMAT,
- val);
- }
- }
if (enabled) val = NV_CTRL_GVO_DISPLAY_X_SCREEN_ENABLE;
else val = NV_CTRL_GVO_DISPLAY_X_SCREEN_DISABLE;
NvCtrlSetAttribute(ctk_gvo->handle, NV_CTRL_GVO_DISPLAY_X_SCREEN, val);
-
+
/*
* XXX NV_CTRL_GVO_DISPLAY_X_SCREEN can silently fail if GLX
* locked GVO output for use by pbuffer(s). Check that the
@@ -1662,6 +1678,8 @@ static void update_offset_spin_button_ranges(CtkGvo *ctk_gvo)
static void update_gvo_sensitivity(CtkGvo *ctk_gvo)
{
gboolean sensitive;
+ guint video_format_valid;
+ gboolean data_format_valid;
sensitive = ((ctk_gvo->lock_owner == NV_CTRL_GVO_LOCK_OWNER_NONE) ||
(ctk_gvo->lock_owner == NV_CTRL_GVO_LOCK_OWNER_CLONE));
@@ -1673,17 +1691,23 @@ static void update_gvo_sensitivity(CtkGvo *ctk_gvo)
/* Video & data formats */
sensitive = (ctk_gvo->lock_owner == NV_CTRL_GVO_LOCK_OWNER_NONE);
+ gtk_widget_set_sensitive(ctk_gvo->output_video_format_menu, sensitive);
gtk_widget_set_sensitive(ctk_gvo->output_data_format_menu, sensitive);
- sensitive = (sensitive && ctk_gvo->has_output_video_formats);
- gtk_widget_set_sensitive(ctk_gvo->output_video_format_menu, sensitive);
-
/* Enable/Disable clone mode button */
+ video_format_valid =
+ ctk_gvo_video_format_valid(ctk_gvo, ctk_gvo->output_video_format);
+
+ data_format_valid =
+ ctk_gvo_data_format_valid(ctk_gvo->output_data_format);
+
sensitive =
+ (ctk_gvo->lock_owner == NV_CTRL_GVO_LOCK_OWNER_CLONE) ||
((ctk_gvo->lock_owner == NV_CTRL_GVO_LOCK_OWNER_NONE) &&
- ctk_gvo->has_output_video_formats) ||
- (ctk_gvo->lock_owner == NV_CTRL_GVO_LOCK_OWNER_CLONE);
+ (video_format_valid == GVO_VIDEO_FORMAT_VALID) &&
+ data_format_valid);
+
gtk_widget_set_sensitive(ctk_gvo->toggle_clone_mode_button, sensitive);
}
@@ -1694,7 +1718,7 @@ static void update_gvo_sensitivity(CtkGvo *ctk_gvo)
/**** Event Handlers *********************************************************/
/*
- * gvo_event_received(() - Handles GVO NV-CONTROL events.
+ * gvo_event_received() - Handles GVO NV-CONTROL events.
*/
static void gvo_event_received(GtkObject *object,
@@ -1714,53 +1738,21 @@ static void gvo_event_received(GtkObject *object,
case NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT:
widget = ctk_gvo->output_video_format_menu;
- g_signal_handlers_block_by_func
- (G_OBJECT(widget),
- G_CALLBACK(output_video_format_ui_changed),
- (gpointer) ctk_gvo);
-
ctk_gvo->output_video_format = value;
- validate_output_video_format(ctk_gvo);
-
- /* Update the dropdown with a reasonable value */
- if (!ctk_gvo->output_video_format_valid) {
- value = get_first_available_output_video_format(ctk_gvo);
- }
- ctk_drop_down_menu_set_current_value
- (CTK_DROP_DOWN_MENU(widget), value);
- post_output_video_format_changed(ctk_gvo);
+ rebuild_output_video_format_menu(ctk_gvo);
- g_signal_handlers_unblock_by_func
- (G_OBJECT(widget),
- G_CALLBACK(output_video_format_ui_changed),
- (gpointer) ctk_gvo);
+ post_output_video_format_changed(ctk_gvo);
break;
case NV_CTRL_GVO_DATA_FORMAT:
widget = ctk_gvo->output_data_format_menu;
-
- g_signal_handlers_block_by_func
- (G_OBJECT(widget),
- G_CALLBACK(output_data_format_ui_changed),
- (gpointer) ctk_gvo);
ctk_gvo->output_data_format = value;
- validate_output_data_format(ctk_gvo);
-
- /* Update the dropdown with a reasonable value */
- if (!ctk_gvo->output_data_format_valid) {
- value = DEFAULT_OUTPUT_DATA_FORMAT;
- }
- ctk_drop_down_menu_set_current_value
- (CTK_DROP_DOWN_MENU(widget), value);
- post_output_data_format_changed(ctk_gvo);
+ rebuild_output_data_format_menu(ctk_gvo);
- g_signal_handlers_unblock_by_func
- (G_OBJECT(widget),
- G_CALLBACK(output_data_format_ui_changed),
- (gpointer) ctk_gvo);
+ post_output_data_format_changed(ctk_gvo);
break;
case NV_CTRL_GVO_X_SCREEN_PAN_X:
@@ -1825,59 +1817,17 @@ static void screen_changed_handler(GtkWidget *widget,
gpointer data)
{
CtkGvo *ctk_gvo = CTK_GVO(data);
- CtkDropDownMenu *dmenu;
- gint val;
/* Cache the new screen dimensions */
ctk_gvo->screen_width = ev->width;
ctk_gvo->screen_height = ev->height;
- /* Update the output video format drop down menu and reset the list */
-
- dmenu = CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu);
-
- /* Get the currently selected value */
-
- val = ctk_drop_down_menu_get_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu));
-
- /* Reset the drop down menu */
-
- ctk_drop_down_menu_reset(dmenu);
-
- /* Fill the menu with the new valid video modes */
-
- fill_output_video_format_menu(ctk_gvo);
-
- /* Finalize and load the menu */
-
- g_signal_handlers_block_by_func
- (G_OBJECT(ctk_gvo->output_video_format_menu),
- G_CALLBACK(output_video_format_ui_changed),
- (gpointer) ctk_gvo);
-
- ctk_drop_down_menu_finalize(dmenu);
-
- /* Set best valid output video format value possible.
- * Revalidate here since the screen change could cause
- * the current output video mode to now be valid.
- */
-
- validate_output_video_format(ctk_gvo);
- if (ctk_gvo->output_video_format_valid) {
- val = ctk_gvo->output_video_format;
- }
-
- ctk_drop_down_menu_set_current_value
- (CTK_DROP_DOWN_MENU(ctk_gvo->output_video_format_menu), val);
+ /* Update UI */
- g_signal_handlers_unblock_by_func
- (G_OBJECT(ctk_gvo->output_video_format_menu),
- G_CALLBACK(output_video_format_ui_changed),
- (gpointer) ctk_gvo);
+ rebuild_output_video_format_menu(ctk_gvo);
- /* Update UI */
+ rebuild_output_data_format_menu(ctk_gvo);
update_gvo_current_info(ctk_gvo);
@@ -1925,7 +1875,7 @@ gint ctk_gvo_probe_callback(gpointer data)
/* update the available output video formats */
- trim_output_video_format_menu(ctk_gvo);
+ rebuild_output_video_format_menu(ctk_gvo);
}
return TRUE;
@@ -2009,7 +1959,12 @@ GtkTextBuffer* ctk_gvo_create_help(GtkTextTagTable *table)
"Free-Running (see Synchronization Options page for more "
"information).", __clone_mode_video_format_help);
ctk_help_heading(b, &i, "Data Format");
- ctk_help_para(b, &i, __clone_mode_data_format_help);
+ ctk_help_para(b, &i, "%s Note that other NV-CONTROL clients are still "
+ "able to select a data format that is not supported with "
+ "clone mode. In this case, the current data format will "
+ "be shown as \"Invalid for Clone Mode\" and you will need "
+ "to select a valid data format in order to enable Clone "
+ "Mode.", __clone_mode_data_format_help);
ctk_help_heading(b, &i, "X Offset");
ctk_help_para(b, &i, __clone_mode_x_offset_help);
ctk_help_heading(b, &i, "Y Offset");
diff --git a/src/gtk+-2.x/ctkgvo.h b/src/gtk+-2.x/ctkgvo.h
index d2201d7..ac3727f 100644
--- a/src/gtk+-2.x/ctkgvo.h
+++ b/src/gtk+-2.x/ctkgvo.h
@@ -75,25 +75,9 @@ struct _CtkGvo
gint input_video_format;
gint output_video_format;
- gint valid_output_video_format_mask[2];
- gboolean has_output_video_formats; // XXX Show show non-valid as gray?
- gboolean output_video_format_valid; /* If the output video format was
- changed by another client to
- something clone mode doesn't
- support, we should ignore it,
- but we should make sure that we
- set the output_video_format when
- we enable clone mode. */
-
-
+ guint valid_output_video_format_mask[2];
+
gint output_data_format;
- gboolean output_data_format_valid; /* If the output data format was
- changed by another client to
- something clone mode doesn't
- support, we should ignore it,
- but we should make sure that we
- set the output_data_format when
- we enable clone mode. */
gint screen_width;
gint screen_height;
diff --git a/src/gtk+-2.x/ctkmultisample.c b/src/gtk+-2.x/ctkmultisample.c
index db90775..9bb4b16 100644
--- a/src/gtk+-2.x/ctkmultisample.c
+++ b/src/gtk+-2.x/ctkmultisample.c
@@ -203,6 +203,8 @@ GtkWidget *ctk_multisample_new(NvCtrlAttributeHandle *handle,
GtkWidget *check_button;
GtkWidget *menu;
GtkWidget *scale;
+ GtkObject *adjustment;
+ gint min, max;
gint val, app_control, override, enhance, i;
@@ -305,6 +307,8 @@ GtkWidget *ctk_multisample_new(NvCtrlAttributeHandle *handle,
gtk_box_pack_start(GTK_BOX(vbox), check_button,
FALSE, FALSE, 0);
+
+ ctk_multisample->fsaa_app_override_check_button = check_button;
}
g_signal_connect(G_OBJECT(ctk_event),
@@ -315,9 +319,13 @@ GtkWidget *ctk_multisample_new(NvCtrlAttributeHandle *handle,
/* Antialiasing scale */
- scale = gtk_hscale_new_with_range
- (0, ctk_multisample->fsaa_translation_table_size - 1, 1);
- gtk_range_set_value(GTK_RANGE(scale), val);
+ min = 0;
+ max = ctk_multisample->fsaa_translation_table_size - 1;
+
+ /* create the slider */
+ adjustment = gtk_adjustment_new(val, min, max, 1, 1, 0.0);
+ scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), val);
gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
@@ -414,9 +422,13 @@ GtkWidget *ctk_multisample_new(NvCtrlAttributeHandle *handle,
/* Aniso scale */
- scale = gtk_hscale_new_with_range(valid.u.range.min,
- valid.u.range.max, 1);
- gtk_range_set_value(GTK_RANGE(scale), val);
+ min = valid.u.range.min;
+ max = valid.u.range.max;
+
+ /* create the slider */
+ adjustment = gtk_adjustment_new(val, min, max, 1, 1, 0.0);
+ scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), val);
gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
diff --git a/src/gtk+-2.x/ctkopengl.c b/src/gtk+-2.x/ctkopengl.c
index b130f3b..8ea1a68 100644
--- a/src/gtk+-2.x/ctkopengl.c
+++ b/src/gtk+-2.x/ctkopengl.c
@@ -28,6 +28,7 @@
#include "ctkbanner.h"
#include "ctkopengl.h"
+#include "ctkscale.h"
#include "ctkconfig.h"
#include "ctkhelp.h"
@@ -44,6 +45,8 @@ static void post_show_sli_hud_button_toggled(CtkOpenGL *, gboolean);
static void post_xinerama_stereo_button_toggled(CtkOpenGL *, gboolean);
+static void post_stereo_eyes_exchange_button_toggled(CtkOpenGL *, gboolean);
+
static void post_aa_line_gamma_toggled(CtkOpenGL *, gboolean);
static void allow_flipping_button_toggled(GtkWidget *, gpointer);
@@ -52,6 +55,8 @@ static void force_stereo_button_toggled (GtkWidget *, gpointer);
static void xinerama_stereo_button_toggled (GtkWidget *, gpointer);
+static void stereo_eyes_exchange_button_toggled (GtkWidget *, gpointer);
+
static void aa_line_gamma_toggled (GtkWidget *, gpointer);
static void show_sli_hud_button_toggled (GtkWidget *, gpointer);
@@ -63,6 +68,11 @@ static const gchar *get_image_settings_string(gint val);
static gchar *format_image_settings_value(GtkScale *scale, gdouble arg1,
gpointer user_data);
+static void post_slider_value_changed(CtkOpenGL *ctk_opengl, gint val);
+
+static void aa_line_gamma_update_received(GtkObject *object,
+ gpointer arg1, gpointer user_data);
+
static void post_image_settings_value_changed(CtkOpenGL *ctk_opengl, gint val);
static void image_settings_value_changed(GtkRange *range, gpointer user_data);
@@ -70,6 +80,15 @@ static void image_settings_value_changed(GtkRange *range, gpointer user_data);
static void image_settings_update_received(GtkObject *object,
gpointer arg1, gpointer user_data);
+static GtkWidget *create_slider(CtkOpenGL *ctk_opengl,
+ GtkWidget *vbox,
+ const gchar *name,
+ const char *help,
+ gint attribute,
+ unsigned int bit);
+
+static void slider_changed(GtkAdjustment *adjustment, gpointer user_data);
+
#define FRAME_PADDING 5
static const char *__sync_to_vblank_help =
@@ -78,6 +97,17 @@ static const char *__sync_to_vblank_help =
"applied to OpenGL applications that are started after "
"this option is set.";
+static const char *__aa_line_gamma_checkbox_help =
+"Enable the antialiased lines gamma correction checkbox to make the "
+"gamma correction slider active.";
+
+static const char *__aa_line_gamma_slider_help =
+"This option allows Gamma-corrected "
+"antialiased lines to consider variances in the color "
+"display capabilities of output devices when rendering "
+"smooth lines. This option is applied to OpenGL applications "
+"that are started after this option is set.";
+
static const char *__image_settings_slider_help =
"The Image Settings slider controls the image quality setting.";
@@ -90,7 +120,7 @@ static const char *__force_stereo_help =
static const char *__xinerama_stereo_help =
"Enabling this option causes OpenGL to allow "
"stereo flipping on multiple X screens configured "
-"with Xinerama. This option is applied immediately.";
+"with Xinerama. This option is applied immediately.";
static const char *__show_sli_hud_help =
"Enabling this option causes OpenGL to draw "
@@ -99,14 +129,21 @@ static const char *__show_sli_hud_help =
"applications that are started after this option is "
"set.";
-#define __SYNC_TO_VBLANK (1 << 1)
-#define __ALLOW_FLIPPING (1 << 2)
-#define __AA_LINE_GAMMA (1 << 3)
-#define __FORCE_GENERIC_CPU (1 << 4)
-#define __FORCE_STEREO (1 << 5)
-#define __IMAGE_SETTINGS (1 << 6)
-#define __XINERAMA_STEREO (1 << 7)
-#define __SHOW_SLI_HUD (1 << 8)
+static const char *__stereo_eyes_exchange_help =
+"Enabling this option causes OpenGL to draw the left "
+"eye image in the right eye and vice versa for stereo "
+"drawables. This option is applied immediately.";
+
+#define __SYNC_TO_VBLANK (1 << 1)
+#define __ALLOW_FLIPPING (1 << 2)
+#define __AA_LINE_GAMMA_VALUE (1 << 3)
+#define __AA_LINE_GAMMA (1 << 4)
+#define __FORCE_GENERIC_CPU (1 << 5)
+#define __FORCE_STEREO (1 << 6)
+#define __IMAGE_SETTINGS (1 << 7)
+#define __XINERAMA_STEREO (1 << 8)
+#define __SHOW_SLI_HUD (1 << 9)
+#define __STEREO_EYES_EXCHANGE (1 << 9)
@@ -150,11 +187,13 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
GtkWidget *vbox;
GtkWidget *check_button;
GtkWidget *scale;
+ GtkObject *adjustment;
gint sync_to_vblank;
gint flipping_allowed;
gint force_stereo;
gint xinerama_stereo;
+ gint stereo_eyes_exchange;
NVCTRLAttributeValidValuesRec image_settings_valid;
gint image_settings_value;
gint aa_line_gamma;
@@ -164,8 +203,9 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
ReturnStatus ret_flipping_allowed;
ReturnStatus ret_force_stereo;
ReturnStatus ret_xinerama_stereo;
+ ReturnStatus ret_stereo_eyes_exchange;
ReturnStatus ret_image_settings;
- ReturnStatus ret_aa_line_gama;
+ ReturnStatus ret_aa_line_gamma;
ReturnStatus ret_show_sli_hud;
/* Query OpenGL settings */
@@ -183,6 +223,10 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
ret_xinerama_stereo =
NvCtrlGetAttribute(handle, NV_CTRL_XINERAMA_STEREO, &xinerama_stereo);
+ ret_stereo_eyes_exchange =
+ NvCtrlGetAttribute(handle, NV_CTRL_STEREO_EYES_EXCHANGE,
+ &stereo_eyes_exchange);
+
ret_image_settings =
NvCtrlGetValidAttributeValues(handle, NV_CTRL_IMAGE_SETTINGS,
&image_settings_valid);
@@ -195,8 +239,8 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
ret_image_settings = NvCtrlError;
}
- ret_aa_line_gama = NvCtrlGetAttribute(handle, NV_CTRL_OPENGL_AA_LINE_GAMMA,
- &aa_line_gamma);
+ ret_aa_line_gamma = NvCtrlGetAttribute(handle, NV_CTRL_OPENGL_AA_LINE_GAMMA,
+ &aa_line_gamma);
ret_show_sli_hud = NvCtrlGetAttribute(handle, NV_CTRL_SHOW_SLI_HUD,
&show_sli_hud);
@@ -205,8 +249,9 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
(ret_flipping_allowed != NvCtrlSuccess) &&
(ret_force_stereo != NvCtrlSuccess) &&
(ret_xinerama_stereo != NvCtrlSuccess) &&
+ (ret_stereo_eyes_exchange != NvCtrlSuccess) &&
(ret_image_settings != NvCtrlSuccess) &&
- (ret_aa_line_gama != NvCtrlSuccess) &&
+ (ret_aa_line_gamma != NvCtrlSuccess) &&
(ret_show_sli_hud != NvCtrlSuccess)) {
return NULL;
}
@@ -368,6 +413,34 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
ctk_opengl->xinerama_stereo_button = check_button;
}
+ if (ret_stereo_eyes_exchange == NvCtrlSuccess) {
+
+ label = gtk_label_new("Exchange Stereo Eyes");
+
+ check_button = gtk_check_button_new();
+ gtk_container_add(GTK_CONTAINER(check_button), label);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button),
+ stereo_eyes_exchange);
+
+ gtk_box_pack_start(GTK_BOX(vbox), check_button, FALSE, FALSE, 0);
+
+ g_signal_connect(G_OBJECT(check_button), "toggled",
+ G_CALLBACK(stereo_eyes_exchange_button_toggled),
+ (gpointer) ctk_opengl);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_STEREO_EYES_EXCHANGE),
+ G_CALLBACK(value_changed), (gpointer) ctk_opengl);
+
+ ctk_config_set_tooltip(ctk_config, check_button,
+ __stereo_eyes_exchange_help);
+
+ ctk_opengl->active_attributes |= __STEREO_EYES_EXCHANGE;
+
+ ctk_opengl->stereo_eyes_exchange_button = check_button;
+ }
+
/*
* Image Quality settings.
*/
@@ -381,9 +454,13 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
gtk_container_set_border_width(GTK_CONTAINER(hbox), FRAME_PADDING);
gtk_container_add(GTK_CONTAINER(frame), hbox);
- scale = gtk_hscale_new_with_range(image_settings_valid.u.range.min,
- image_settings_valid.u.range.max, 1);
- gtk_range_set_value(GTK_RANGE(scale), image_settings_value);
+ /* create the slider */
+ adjustment = gtk_adjustment_new(image_settings_value,
+ image_settings_valid.u.range.min,
+ image_settings_valid.u.range.max,
+ 1, 1, 0.0);
+ scale = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment), image_settings_value);
gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
@@ -430,7 +507,7 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
* NV_CTRL_OPENGL_AA_LINE_GAMMA
*/
- if (ret_aa_line_gama == NvCtrlSuccess) {
+ if (ret_aa_line_gamma == NvCtrlSuccess) {
label = gtk_label_new("Enable gamma correction for antialiased lines");
check_button = gtk_check_button_new();
@@ -451,14 +528,26 @@ GtkWidget* ctk_opengl_new(NvCtrlAttributeHandle *handle,
G_CALLBACK(value_changed), (gpointer) ctk_opengl);
ctk_config_set_tooltip(ctk_opengl->ctk_config,
- check_button, "Allow Gamma-corrected "
- "antialiased lines to consider variances in "
- "the color display capabilities of output "
- "devices when rendering smooth lines");
-
+ check_button, __aa_line_gamma_checkbox_help);
+
+ ctk_opengl->aa_line_gamma_button = check_button;
ctk_opengl->active_attributes |= __AA_LINE_GAMMA;
+
+ ctk_opengl->aa_line_gamma_scale =
+ create_slider(ctk_opengl, vbox, "Gamma correction",
+ __aa_line_gamma_slider_help,
+ NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE,
+ __AA_LINE_GAMMA_VALUE);
+
+ g_signal_connect(G_OBJECT(ctk_event),
+ CTK_EVENT_NAME(NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE),
+ G_CALLBACK(aa_line_gamma_update_received),
+ (gpointer) ctk_opengl);
- ctk_opengl->aa_line_gamma_button = check_button;
+ if (ctk_opengl->aa_line_gamma_scale)
+ gtk_widget_set_sensitive(ctk_opengl->aa_line_gamma_scale,
+ gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(check_button)));
}
if (ret_show_sli_hud == NvCtrlSuccess) {
@@ -537,6 +626,14 @@ static void post_xinerama_stereo_button_toggled(CtkOpenGL *ctk_opengl,
enabled ? "allowed" : "not allowed");
}
+static void post_stereo_eyes_exchange_button_toggled(CtkOpenGL *ctk_opengl,
+ gboolean enabled)
+{
+ ctk_config_statusbar_message(ctk_opengl->ctk_config,
+ "OpenGL Stereo Eyes Exchanged %s.",
+ enabled ? "enabled" : "disabled");
+}
+
static void post_aa_line_gamma_toggled(CtkOpenGL *ctk_opengl,
gboolean enabled)
{
@@ -622,6 +719,22 @@ static void xinerama_stereo_button_toggled(GtkWidget *widget,
post_xinerama_stereo_button_toggled(ctk_opengl, enabled);
}
+static void stereo_eyes_exchange_button_toggled(GtkWidget *widget,
+ gpointer user_data)
+{
+ CtkOpenGL *ctk_opengl;
+ gboolean enabled;
+
+ ctk_opengl = CTK_OPENGL(user_data);
+
+ enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ NvCtrlSetAttribute(ctk_opengl->handle, NV_CTRL_STEREO_EYES_EXCHANGE,
+ enabled);
+
+ post_stereo_eyes_exchange_button_toggled(ctk_opengl, enabled);
+}
+
static void aa_line_gamma_toggled(
GtkWidget *widget,
gpointer user_data
@@ -639,6 +752,8 @@ static void aa_line_gamma_toggled(
NV_CTRL_OPENGL_AA_LINE_GAMMA, enabled);
if (ret != NvCtrlSuccess) return;
+ if (ctk_opengl->aa_line_gamma_scale)
+ gtk_widget_set_sensitive(ctk_opengl->aa_line_gamma_scale, enabled);
post_aa_line_gamma_toggled(ctk_opengl, enabled);
}
@@ -680,10 +795,18 @@ static void value_changed(GtkObject *object, gpointer arg1, gpointer user_data)
func = G_CALLBACK(xinerama_stereo_button_toggled);
post_xinerama_stereo_button_toggled(ctk_opengl, event_struct->value);
break;
+ case NV_CTRL_STEREO_EYES_EXCHANGE:
+ button = GTK_TOGGLE_BUTTON(ctk_opengl->stereo_eyes_exchange_button);
+ func = G_CALLBACK(stereo_eyes_exchange_button_toggled);
+ post_stereo_eyes_exchange_button_toggled(ctk_opengl,
+ event_struct->value);
+ break;
case NV_CTRL_OPENGL_AA_LINE_GAMMA:
button = GTK_TOGGLE_BUTTON(ctk_opengl->aa_line_gamma_button);
func = G_CALLBACK(aa_line_gamma_toggled);
post_aa_line_gamma_toggled(ctk_opengl, event_struct->value);
+ gtk_widget_set_sensitive(ctk_opengl->aa_line_gamma_scale,
+ event_struct->value);
break;
case NV_CTRL_SHOW_SLI_HUD:
button = GTK_TOGGLE_BUTTON(ctk_opengl->show_sli_hud_button);
@@ -791,6 +914,122 @@ static void image_settings_update_received(GtkObject *object,
} /* image_settings_update_received() */
+/*
+ * post_slider_value_changed() - helper function for
+ * aa_line_gamma_value_changed(); this does whatever work is necessary
+ * after the aa line gamma value has changed.
+ */
+
+static void post_slider_value_changed(CtkOpenGL *ctk_opengl, gint val)
+{
+ ctk_config_statusbar_message(ctk_opengl->ctk_config,
+ "OpenGL anti-aliased lines edge smoothness "
+ "changed to %d\%.",
+ val);
+
+} /* post_slider_value_changed() */
+
+
+/*
+ * slider_changed() -
+ */
+
+static void slider_changed(GtkAdjustment *adjustment, gpointer user_data)
+{
+ CtkOpenGL *ctk_opengl = CTK_OPENGL(user_data);
+ gint attribute, value;
+ user_data = g_object_get_data(G_OBJECT(adjustment), "opengl_attribute");
+ attribute = GPOINTER_TO_INT(user_data);
+ value = (gint) adjustment->value;
+ NvCtrlSetAttribute(ctk_opengl->handle, attribute, value);
+ post_slider_value_changed(ctk_opengl, value);
+} /* slider_changed() */
+
+
+/*
+ * aa_line_gamma_update_received() - this function is called when the
+ * NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE atribute is changed by another NV-CONTROL
+ * client.
+ */
+
+static void aa_line_gamma_update_received(GtkObject *object,
+ gpointer arg1, gpointer user_data)
+{
+ CtkEventStruct *event_struct = (CtkEventStruct *) arg1;
+ CtkOpenGL *ctk_opengl = CTK_OPENGL(user_data);
+ CtkScale *scale = CTK_SCALE(ctk_opengl->aa_line_gamma_scale);
+ GtkAdjustment *adjustment;
+ adjustment = GTK_ADJUSTMENT(scale->gtk_adjustment);
+ g_signal_handlers_block_by_func(G_OBJECT(adjustment),
+ G_CALLBACK(slider_changed),
+ (gpointer) ctk_opengl);
+
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(adjustment),
+ (gint)event_struct->value);
+ post_slider_value_changed(ctk_opengl, event_struct->value);
+
+ g_signal_handlers_unblock_by_func(G_OBJECT(adjustment),
+ G_CALLBACK(slider_changed),
+ (gpointer) ctk_opengl);
+
+} /* aa_line_gamma_update_received() */
+
+
+
+static GtkWidget *create_slider(CtkOpenGL *ctk_opengl,
+ GtkWidget *vbox,
+ const gchar *name,
+ const char *help,
+ gint attribute,
+ unsigned int bit)
+{
+ GtkObject *adjustment;
+ GtkWidget *scale, *widget;
+ gint min, max, val, step_incr, page_incr;
+ NVCTRLAttributeValidValuesRec range;
+ ReturnStatus ret;
+ /* get the attribute value */
+
+ ret = NvCtrlGetAttribute(ctk_opengl->handle, attribute, &val);
+ if (ret != NvCtrlSuccess) return NULL;
+ /* get the range for the attribute */
+
+ NvCtrlGetValidAttributeValues(ctk_opengl->handle, attribute, &range);
+
+ if (range.type != ATTRIBUTE_TYPE_RANGE) return NULL;
+ min = range.u.range.min;
+ max = range.u.range.max;
+
+ step_incr = ((max) - (min))/10;
+ if (step_incr <= 0) step_incr = 1;
+ page_incr = ((max) - (min))/25;
+ if (page_incr <= 0) page_incr = 1;
+
+ /* create the slider */
+ adjustment = gtk_adjustment_new(val, min, max,
+ step_incr, page_incr, 0.0);
+
+ g_object_set_data(G_OBJECT(adjustment), "opengl_attribute",
+ GINT_TO_POINTER(attribute));
+
+ g_signal_connect(G_OBJECT(adjustment), "value_changed",
+ G_CALLBACK(slider_changed),
+ (gpointer) ctk_opengl);
+
+ scale = ctk_scale_new(GTK_ADJUSTMENT(adjustment), name,
+ ctk_opengl->ctk_config, G_TYPE_INT);
+
+ gtk_box_pack_start(GTK_BOX(vbox), scale, TRUE, TRUE, 0);
+
+ ctk_opengl->active_attributes |= bit;
+
+ widget = CTK_SCALE(scale)->gtk_scale;
+ ctk_config_set_tooltip(ctk_opengl->ctk_config, widget, help);
+
+ return scale;
+} /* create_slider() */
+
+
GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table,
CtkOpenGL *ctk_opengl)
{
@@ -835,6 +1074,11 @@ GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table,
ctk_help_para(b, &i, __xinerama_stereo_help);
}
+ if (ctk_opengl->active_attributes & __STEREO_EYES_EXCHANGE) {
+ ctk_help_heading(b, &i, "Exchange Stereo Eyes");
+ ctk_help_para(b, &i, __stereo_eyes_exchange_help);
+ }
+
if (ctk_opengl->active_attributes & __IMAGE_SETTINGS) {
ctk_help_heading(b, &i, "Image Settings");
ctk_help_para(b, &i, "This setting gives you full control over the "
@@ -871,13 +1115,13 @@ GtkTextBuffer *ctk_opengl_create_help(GtkTextTagTable *table,
if (ctk_opengl->active_attributes & __AA_LINE_GAMMA) {
ctk_help_heading(b, &i, "Enable gamma correction for "
"antialiased lines");
- ctk_help_para(b, &i, "Enabling this option allows Gamma-corrected "
- "antialiased lines to consider variances in the color "
- "display capabilities of output devices when rendering "
- "smooth lines. This option is available only on "
- "Quadro FX or newer NVIDIA GPUs. This option is "
- "applied to OpenGL applications that are started after "
- "this option is set.");
+ ctk_help_para(b, &i, __aa_line_gamma_checkbox_help );
+ }
+
+ if (ctk_opengl->active_attributes & __AA_LINE_GAMMA_VALUE) {
+ ctk_help_heading(b, &i, "Set gamma correction for "
+ "antialiased lines");
+ ctk_help_para(b, &i, __aa_line_gamma_slider_help);
}
if (ctk_opengl->active_attributes & __SHOW_SLI_HUD) {
diff --git a/src/gtk+-2.x/ctkopengl.h b/src/gtk+-2.x/ctkopengl.h
index ff37a0c..0a693dc 100644
--- a/src/gtk+-2.x/ctkopengl.h
+++ b/src/gtk+-2.x/ctkopengl.h
@@ -62,8 +62,10 @@ struct _CtkOpenGL
GtkWidget *allow_flipping_button;
GtkWidget *force_stereo_button;
GtkWidget *xinerama_stereo_button;
+ GtkWidget *stereo_eyes_exchange_button;
GtkWidget *image_settings_scale;
GtkWidget *aa_line_gamma_button;
+ GtkWidget *aa_line_gamma_scale;
GtkWidget *show_sli_hud_button;
unsigned int active_attributes;
diff --git a/src/gtk+-2.x/ctkslimm.c b/src/gtk+-2.x/ctkslimm.c
index ebd4732..1f6b1bd 100644
--- a/src/gtk+-2.x/ctkslimm.c
+++ b/src/gtk+-2.x/ctkslimm.c
@@ -74,6 +74,10 @@ static const GridConfig gridConfigs[] = {
{3, 1},
{3, 2},
{1, 3},
+ {2, 1},
+ {1, 2},
+ {4, 1},
+ {1, 4},
{0, 0}
};
diff --git a/src/gtk+-2.x/ctkwindow.c b/src/gtk+-2.x/ctkwindow.c
index 3eed0e6..cb93c33 100644
--- a/src/gtk+-2.x/ctkwindow.c
+++ b/src/gtk+-2.x/ctkwindow.c
@@ -387,6 +387,9 @@ GtkWidget *ctk_window_new(NvCtrlAttributeHandle **screen_handles,
GtkWidget *toggle_button;
GtkWidget *statusbar;
GtkWidget *eventbox;
+ GtkWidget *label;
+ GtkRequisition req;
+ gint width;
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
@@ -591,7 +594,8 @@ GtkWidget *ctk_window_new(NvCtrlAttributeHandle **screen_handles,
CTK_DISPLAY_CONFIG(child)),
ctk_window, NULL, NULL,
"X Server Display Configuration",
- NULL, NULL, NULL);
+ NULL, ctk_display_config_selected,
+ ctk_display_config_unselected);
}
}
}
@@ -965,6 +969,31 @@ GtkWidget *ctk_window_new(NvCtrlAttributeHandle **screen_handles,
gtk_widget_show_all(GTK_WIDGET(object));
+
+ /* Set the minimum width of the tree view window to be something
+ * reasonable. To do that, check the size of a label widget
+ * with a reasonably long string and limit the tree view scroll
+ * window's initial width to not extent past this.
+ */
+
+ label = gtk_label_new("XXXXXX Server Display ConfigurationXXXX");
+ gtk_widget_size_request(label, &req);
+ width = req.width;
+ gtk_widget_destroy(label);
+
+ /* Get the width of the tree view scroll window */
+ gtk_widget_size_request(sw, &req);
+
+ /* If the scroll window is too wide, make it slimmer and
+ * allow users to scroll horizontally (also allow resizing).
+ */
+ if ( width < req.width ) {
+ gtk_widget_set_size_request(sw, width, -1);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ }
+
return GTK_WIDGET(object);
} /* ctk_window_new() */
@@ -1291,16 +1320,15 @@ static void update_display_devices(GtkObject *object, gpointer arg1,
gtk_tree_selection_select_iter(tree_selection, &parent_iter);
}
- /* unref the page so we don't leak memory */
+ /* Remove the entry */
gtk_tree_model_get(GTK_TREE_MODEL(ctk_window->tree_store), iter,
CTK_WINDOW_WIDGET_COLUMN, &widget, -1);
- g_object_unref(widget);
-
- /* XXX Call a widget-specific cleanup function? */
-
- /* Remove the entry */
+
gtk_tree_store_remove(ctk_window->tree_store, iter);
+ /* unref the page so we don't leak memory */
+ g_object_unref(GTK_OBJECT(widget));
+
data->num_displays--;
}
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index 8082311..5e79a88 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -3322,6 +3322,23 @@
#define NV_CTRL_DEPTH_30_ALLOWED 279 /* R--G */
/*
+ * NV_CTRL_MODE_SET_EVENT This attribute is sent as an event
+ * when hotkey, ctrl-alt-+/- or randr event occurs. Note that
+ * This attribute cannot be set or queried and is meant to
+ * be received by clients that wish to be notified of when
+ * mode set events occur.
+ */
+
+#define NV_CTRL_MODE_SET_EVENT 280 /* --- */
+
+/*
+ * NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE - the gamma value used by
+ * OpenGL when NV_CTRL_OPENGL_AA_LINE_GAMMA is enabled
+ */
+
+#define NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE 281 /* RW-X */
+
+/*
* NV_CTRL_DISPLAYPORT_LINK_RATE - returns the negotiated lane bandwidth of the
* DisplayPort main link.
* This attribute is only available for DisplayPort flat panels.
@@ -3332,7 +3349,35 @@
#define NV_CTRL_DISPLAYPORT_LINK_RATE_1_62GBPS 0x6
#define NV_CTRL_DISPLAYPORT_LINK_RATE_2_70GBPS 0xA
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DISPLAYPORT_LINK_RATE
+/*
+ * NV_CTRL_STEREO_EYES_EXCHANGE - Controls whether or not the left and right
+ * eyes of a stereo image are flipped.
+ */
+
+#define NV_CTRL_STEREO_EYES_EXCHANGE 292 /* RW-X */
+#define NV_CTRL_STEREO_EYES_EXCHANGE_OFF 0
+#define NV_CTRL_STEREO_EYES_EXCHANGE_ON 1
+
+/*
+ * NV_CTRL_NO_SCANOUT - returns whether the special "NoScanout" mode is
+ * enabled on the specified X screen or GPU; for details on this mode,
+ * see the description of the "none" value for the "UseDisplayDevice"
+ * X configuration option in the NVIDIA driver README.
+ */
+
+#define NV_CTRL_NO_SCANOUT 293 /* R--G */
+#define NV_CTRL_NO_SCANOUT_DISABLED 0
+#define NV_CTRL_NO_SCANOUT_ENABLED 1
+
+/*
+ * NV_CTRL_GVO_CSC_CHANGED_EVENT This attribute is sent as an event
+ * when the color space conversion matrix has been altered by another
+ * client.
+ */
+
+#define NV_CTRL_GVO_CSC_CHANGED_EVENT 294 /* --- */
+
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_GVO_CSC_CHANGED_EVENT
/**************************************************************************/
diff --git a/src/lscf.c b/src/lscf.c
new file mode 100644
index 0000000..cf4e66b
--- /dev/null
+++ b/src/lscf.c
@@ -0,0 +1,275 @@
+#include <stdio.h>
+#if defined(NV_SUNOS)
+
+/* Interface to the Solaris Service Management Facility.
+ * This facility is responsible for running programs and services
+ * and store their configuration informations (named properties)
+ * The configuration informations for the X server are managed by
+ * this facility. The functions in this source file use the library
+ * libscf (Service Configuration Facility) to access and modify
+ * the properties for the X server, more specifically the default depth.
+ * On Solaris, changing the default depth in the xorg.conf file is not
+ * enough. The session manager overrides the xorg.conf default depth:
+ * it passes the option -defdepth to the X server with the value
+ * retrieved from the Service Management Facility.
+ *
+ * For more information refer to the manpages of fmf(5), libsfc(3LIB),
+ * and to the source code of svccfg(1M) available on cvs.opensolaris.org.
+ */
+
+
+#include <libscf.h>
+
+static int lscf_init_handle(scf_handle_t **scf_handle,
+ scf_scope_t **scf_scope);
+static int lscf_select(scf_handle_t *scf_handle,
+ scf_scope_t *scf_scope,
+ const char *selection,
+ scf_service_t **current_svc);
+static int lscf_setprop_int(scf_handle_t *scf_handle,
+ scf_scope_t *scf_scope,
+ scf_service_t *current_svc,
+ const char *group,
+ const char *name, int value);
+
+/* UPDATE THE DEFAULT DEPTH PROPERTY IN SMF WITH THE LIBSCF FUNCTIONS */
+int update_scf_depth(int depth)
+{
+ static scf_handle_t *scf_handle = NULL;
+ static scf_scope_t *scf_scope = NULL;
+ scf_service_t *curren_svc = NULL;
+ int status = 1;
+
+ // Initialization of the handles
+ lscf_init_handle(&scf_handle, &scf_scope);
+ if (scf_handle == NULL) {
+ status =0;
+ goto done;
+ }
+
+ // Set the current selection
+ if(!lscf_select(scf_handle, scf_scope, "application/x11/x11-server",
+ &curren_svc)) {
+ status =0;
+ goto done;
+ }
+
+ // Set the depth property of the current selection
+ if(!lscf_setprop_int(scf_handle, scf_scope, curren_svc,
+ "options", "default_depth", depth)) {
+ status =0;
+ goto done;
+ }
+
+done:
+ if(curren_svc) scf_service_destroy(curren_svc);
+ if(scf_scope) scf_scope_destroy(scf_scope);
+ if(scf_handle) {
+ scf_handle_unbind(scf_handle);
+ scf_handle_destroy(scf_handle);
+ }
+ if (!status) {
+ fmterr("Unable to set X server default depth through "
+ "Solaris Service Management Facility");
+ }
+ return status;
+}
+
+/* INITIALIZATION OF THE HANDLES */
+static int lscf_init_handle(scf_handle_t **scf_handle,
+ scf_scope_t **scf_scope)
+{
+ scf_handle_t *handle = NULL;
+ scf_scope_t *scope = NULL;;
+
+ *scf_handle = NULL;
+ *scf_scope = NULL;
+
+ // Create a new Service Configuration Facility
+ // handle, needed for the communication with the
+ // configuration repository.
+ handle = scf_handle_create(SCF_VERSION);
+ if (handle == NULL) {
+ return 0;
+ }
+
+ // Bind the handle to the running svc.config daemon
+ if (scf_handle_bind(handle) != 0) {
+ scf_handle_destroy(handle);
+ return 0;
+ }
+
+
+ // Allocate a new scope. A scope is a top level of the
+ // SCF repository tree.
+ scope = scf_scope_create(handle);
+ if (scope == NULL) {
+ scf_handle_unbind(handle);
+ scf_handle_destroy(handle);
+ return 0;
+ }
+
+ // Set the scope to the root of the local SCF repository tree.
+ if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) !=0) {
+ scf_scope_destroy(scope);
+ scf_handle_unbind(handle);
+ scf_handle_destroy(handle);
+ return 0;
+ }
+
+ *scf_handle = handle;
+ *scf_scope = scope;
+
+ return 1;
+}
+
+
+/* EQUIVALENT TO THE SVCCFG SELECT COMMAND */
+static int lscf_select(scf_handle_t *scf_handle,
+ scf_scope_t *scf_scope,
+ const char *selection,
+ scf_service_t **current_svc)
+{
+ scf_service_t *svc;
+
+ // Services are childrens of a scope, and
+ // contain configuration informations for
+ // the service.
+ svc = scf_service_create(scf_handle);
+ if (svc == NULL) {
+ return 0;
+ }
+
+ // Set the service 'svc' to the service specified
+ // by 'selection', in the scope 'scf_scope'.
+ if (scf_scope_get_service(scf_scope, selection, svc) == SCF_SUCCESS) {
+ *current_svc = svc;
+ return 1;
+ }
+
+ scf_service_destroy(svc);
+ return 0;
+}
+
+/* EQUIVALENT TO THE SVCCFG SETPROP COMMAND FOR AN INTEGER TYPED VALUE */
+static int lscf_setprop_int(scf_handle_t *scf_handle,
+ scf_scope_t *scf_scope,
+ scf_service_t *current_svc,
+ const char *group,
+ const char *name, int value)
+{
+ scf_transaction_entry_t *entry=NULL;
+ scf_propertygroup_t *pg = NULL;
+ scf_property_t *prop = NULL;
+ scf_transaction_t *transax = NULL;
+ scf_value_t *v = NULL;
+ int status = 1;
+
+ // Allocate a new transaction entry handle
+ entry = scf_entry_create(scf_handle);
+ if (entry == NULL) {
+ status=0;
+ goto done;
+ }
+
+ // Allocate a property group.
+ pg = scf_pg_create(scf_handle);
+ if (pg == NULL) {
+ status=0;
+ goto done;
+ }
+
+ // Allocate a property. A property is a named set
+ // of values.
+ prop = scf_property_create(scf_handle);
+ if (prop == NULL) {
+ status=0;
+ goto done;
+ }
+
+ // Allocate a transaction, used to change
+ // property groups.
+ transax = scf_transaction_create(scf_handle);
+ if (transax == NULL) {
+ status=0;
+ goto done;
+ }
+
+ // Allocate a value.
+ v = scf_value_create(scf_handle);
+ if (v == NULL) {
+ status=0;
+ goto done;
+ }
+
+ // Set the the property group 'pg' to the
+ // groups specified by 'group' in the service
+ // specified by 'current_svc'
+ if (scf_service_get_pg(current_svc, group, pg) != SCF_SUCCESS) {
+ status=0;
+ goto done;
+ }
+
+ // Update the property group.
+ if (scf_pg_update(pg) == -1) {
+ status=0;
+ goto done;
+ }
+
+ // Set up the transaction to modify the property group.
+ if (scf_transaction_start(transax, pg) != SCF_SUCCESS) {
+ status=0;
+ goto done;
+ }
+
+ // Set the property 'prop' to the property
+ // specified ny 'name' in the property group 'pg'
+ if (scf_pg_get_property(pg, name, prop) == SCF_SUCCESS) {
+ // Found
+ // It should be already of integer type.
+ // To be secure, reset the property type to integer.
+ if (scf_transaction_property_change_type(transax, entry,
+ name, SCF_TYPE_INTEGER) == -1) {
+ status=0;
+ goto done;
+ }
+ } else {
+ // Not found
+ // Add a new property to the property group.
+ if (scf_transaction_property_new(transax, entry,
+ name, SCF_TYPE_INTEGER)
+ == -1) {
+ status=0;
+ goto done;
+ }
+ }
+
+ // Set the integer value
+ scf_value_set_integer(v, value);
+
+ // Set up the value to the property.
+ if (scf_entry_add_value(entry, v) != SCF_SUCCESS) {
+ status=0;
+ goto done;
+ }
+
+ // Commit the transaction
+ if (scf_transaction_commit(transax) < 0) {
+ status=0;
+ }
+
+done:
+ if (entry) scf_entry_destroy(entry);
+ if (pg) scf_pg_destroy(pg);
+ if (prop) scf_property_destroy(prop);
+ if (transax) scf_transaction_destroy(transax);
+ if (v) scf_value_destroy(v);
+ return status;
+}
+
+#else // NOT SOLARIS
+int update_scf_depth(int depth)
+{
+ return 1;
+}
+#endif
diff --git a/src/lscf.h b/src/lscf.h
new file mode 100644
index 0000000..936817d
--- /dev/null
+++ b/src/lscf.h
@@ -0,0 +1,31 @@
+/*
+ * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
+ * and Linux systems.
+ *
+ * Copyright (C) 2004 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of Version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2
+ * of the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the:
+ *
+ * Free Software Foundation, Inc.
+ * 59 Temple Place - Suite 330
+ * Boston, MA 02111-1307, USA
+ *
+ */
+
+#ifndef __LSCF_H__
+#define __LSCF_H__
+
+/* lscf.c */
+int update_scf_depth(int depth);
+
+#endif /* __LSCF_H__ */
diff --git a/src/parse.c b/src/parse.c
index d55b146..ec19f0b 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -88,6 +88,7 @@ AttributeTableEntry attributeTable[] = {
{ "Overlay", NV_CTRL_OVERLAY, 0 },
{ "HWOverlay", NV_CTRL_HWOVERLAY, 0 },
{ "Stereo", NV_CTRL_STEREO, 0 },
+ { "StereoEyesExchange", NV_CTRL_STEREO_EYES_EXCHANGE, 0 },
{ "TwinView", NV_CTRL_TWINVIEW, 0 },
{ "ConnectedDisplays", NV_CTRL_CONNECTED_DISPLAYS, D },
{ "EnabledDisplays", NV_CTRL_ENABLED_DISPLAYS, D },
@@ -97,7 +98,9 @@ AttributeTableEntry attributeTable[] = {
{ "AssociatedDisplays", NV_CTRL_ASSOCIATED_DISPLAY_DEVICES, N|D },
{ "ProbeDisplays", NV_CTRL_PROBE_DISPLAYS, A },
{ "Depth30Allowed", NV_CTRL_DEPTH_30_ALLOWED, N },
+ { "NoScanout", NV_CTRL_NO_SCANOUT, N },
{ "ForceGenericCpu", NV_CTRL_FORCE_GENERIC_CPU, N },
+ { "GammaCorrectedAALinesValue", NV_CTRL_OPENGL_AA_LINE_GAMMA_VALUE, 0 },
{ "GammaCorrectedAALines", NV_CTRL_OPENGL_AA_LINE_GAMMA, 0 },
{ "ShowSLIHUD", NV_CTRL_SHOW_SLI_HUD, 0 },
{ "CursorShadow", NV_CTRL_CURSOR_SHADOW, 0 },
@@ -260,7 +263,7 @@ AttributeTableEntry attributeTable[] = {
* about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DISPLAYPORT_LINK_RATE
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GVO_CSC_CHANGED_EVENT
#warning "Have you forgotten to add a new integer attribute to attributeTable?"
#endif
@@ -318,7 +321,6 @@ int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *a)
int len, ret;
#define stop(x) { if (no_spaces) free(no_spaces); return (x); }
-
if (!a) stop(NV_PARSER_STATUS_BAD_ARGUMENT);
/* clear the ParsedAttribute struct */
@@ -415,11 +417,14 @@ int nv_parse_attribute_string(const char *str, int query, ParsedAttribute *a)
/*
* Either a single 32-bit integer or two 16-bit
* integers, separated by ','.
+ * Passing base as 0 allows packed values to be specified
+ * in hex (Bug 377242)
*/
- a->val = strtol(s, &tmp, 10);
+ a->val = strtol(s, &tmp, 0);
+
if (tmp && *tmp == ',') {
a->val = (a->val & 0xffff) << 16;
- a->val |= strtol((tmp + 1), &tmp, 10) & 0xffff;
+ a->val |= strtol((tmp + 1), &tmp, 0) & 0xffff;
}
} else if (a->flags & NV_PARSER_TYPE_VALUE_IS_DISPLAY) {
if (nv_strcasecmp(s, "alldisplays")) {